
obj/kern/kernel:     file format elf32-i386


Disassembly of section .text:

f0100000 <_start-0xc>:
.long MULTIBOOT_HEADER_FLAGS
.long CHECKSUM

.globl		_start
_start:
	movw	$0x1234,0x472			# warm boot
f0100000:	02 b0 ad 1b 03 00    	add    0x31bad(%eax),%dh
f0100006:	00 00                	add    %al,(%eax)
f0100008:	fb                   	sti    
f0100009:	4f                   	dec    %edi
f010000a:	52                   	push   %edx
f010000b:	e4 66                	in     $0x66,%al

f010000c <_start>:
f010000c:	66 c7 05 72 04 00 00 	movw   $0x1234,0x472
f0100013:	34 12 

	# Establish our own GDT in place of the boot loader's temporary GDT.
	lgdt	RELOC(mygdtdesc)		# load descriptor table
f0100015:	0f 01 15 18 e0 11 00 	lgdtl  0x11e018

	# Immediately reload all segment registers (including CS!)
	# with segment selectors from the new GDT.
	movl	$DATA_SEL, %eax			# Data segment selector
f010001c:	b8 10 00 00 00       	mov    $0x10,%eax
	movw	%ax,%ds				# -> DS: Data Segment
f0100021:	8e d8                	mov    %eax,%ds
	movw	%ax,%es				# -> ES: Extra Segment
f0100023:	8e c0                	mov    %eax,%es
	movw	%ax,%ss				# -> SS: Stack Segment
f0100025:	8e d0                	mov    %eax,%ss
	ljmp	$CODE_SEL,$relocated		# reload CS by jumping
f0100027:	ea 2e 00 10 f0 08 00 	ljmp   $0x8,$0xf010002e

f010002e <relocated>:
relocated:

	# Clear the frame pointer register (EBP)
	# so that once we get into debugging C code,
	# stack backtraces will be terminated properly.
	movl	$0x0,%ebp			# nuke frame pointer
f010002e:	bd 00 00 00 00       	mov    $0x0,%ebp

	# Leave a few words on the stack for the user trap frame
	movl	$(bootstacktop-SIZEOF_STRUCT_TRAPFRAME),%esp
f0100033:	bc bc df 11 f0       	mov    $0xf011dfbc,%esp

	# now to C code
	call	i386_init
f0100038:	e8 a7 00 00 00       	call   f01000e4 <i386_init>

f010003d <spin>:

	# Should never get here, but in case we do, just spin.
spin:	jmp	spin
f010003d:	eb fe                	jmp    f010003d <spin>
	...

f0100040 <_warn>:
}

/* like panic, but don't */
void
_warn(const char *file, int line, const char *fmt,...)
{
f0100040:	55                   	push   %ebp
f0100041:	89 e5                	mov    %esp,%ebp
f0100043:	53                   	push   %ebx
f0100044:	83 ec 14             	sub    $0x14,%esp
		monitor(NULL);
}

/* like panic, but don't */
void
_warn(const char *file, int line, const char *fmt,...)
f0100047:	8d 5d 14             	lea    0x14(%ebp),%ebx
{
	va_list ap;

	va_start(ap, fmt);
	cprintf("kernel warning at %s:%d: ", file, line);
f010004a:	8b 45 0c             	mov    0xc(%ebp),%eax
f010004d:	89 44 24 08          	mov    %eax,0x8(%esp)
f0100051:	8b 45 08             	mov    0x8(%ebp),%eax
f0100054:	89 44 24 04          	mov    %eax,0x4(%esp)
f0100058:	c7 04 24 20 69 10 f0 	movl   $0xf0106920,(%esp)
f010005f:	e8 7b 39 00 00       	call   f01039df <cprintf>
	vcprintf(fmt, ap);
f0100064:	89 5c 24 04          	mov    %ebx,0x4(%esp)
f0100068:	8b 45 10             	mov    0x10(%ebp),%eax
f010006b:	89 04 24             	mov    %eax,(%esp)
f010006e:	e8 39 39 00 00       	call   f01039ac <vcprintf>
	cprintf("\n");
f0100073:	c7 04 24 62 78 10 f0 	movl   $0xf0107862,(%esp)
f010007a:	e8 60 39 00 00       	call   f01039df <cprintf>
	va_end(ap);
}
f010007f:	83 c4 14             	add    $0x14,%esp
f0100082:	5b                   	pop    %ebx
f0100083:	5d                   	pop    %ebp
f0100084:	c3                   	ret    

f0100085 <_panic>:
 * Panic is called on unresolvable fatal errors.
 * It prints "panic: mesg", and then enters the kernel monitor.
 */
void
_panic(const char *file, int line, const char *fmt,...)
{
f0100085:	55                   	push   %ebp
f0100086:	89 e5                	mov    %esp,%ebp
f0100088:	56                   	push   %esi
f0100089:	53                   	push   %ebx
f010008a:	83 ec 10             	sub    $0x10,%esp
f010008d:	8b 75 10             	mov    0x10(%ebp),%esi
	va_list ap;

	if (panicstr)
f0100090:	83 3d 00 f0 2c f0 00 	cmpl   $0x0,0xf02cf000
f0100097:	75 3d                	jne    f01000d6 <_panic+0x51>
		goto dead;
	panicstr = fmt;
f0100099:	89 35 00 f0 2c f0    	mov    %esi,0xf02cf000

	// Be extra sure that the machine is in as reasonable state
	__asm __volatile("cli; cld");
f010009f:	fa                   	cli    
f01000a0:	fc                   	cld    
/*
 * Panic is called on unresolvable fatal errors.
 * It prints "panic: mesg", and then enters the kernel monitor.
 */
void
_panic(const char *file, int line, const char *fmt,...)
f01000a1:	8d 5d 14             	lea    0x14(%ebp),%ebx

	// Be extra sure that the machine is in as reasonable state
	__asm __volatile("cli; cld");

	va_start(ap, fmt);
	cprintf("kernel panic at %s:%d: ", file, line);
f01000a4:	8b 45 0c             	mov    0xc(%ebp),%eax
f01000a7:	89 44 24 08          	mov    %eax,0x8(%esp)
f01000ab:	8b 45 08             	mov    0x8(%ebp),%eax
f01000ae:	89 44 24 04          	mov    %eax,0x4(%esp)
f01000b2:	c7 04 24 3a 69 10 f0 	movl   $0xf010693a,(%esp)
f01000b9:	e8 21 39 00 00       	call   f01039df <cprintf>
	vcprintf(fmt, ap);
f01000be:	89 5c 24 04          	mov    %ebx,0x4(%esp)
f01000c2:	89 34 24             	mov    %esi,(%esp)
f01000c5:	e8 e2 38 00 00       	call   f01039ac <vcprintf>
	cprintf("\n");
f01000ca:	c7 04 24 62 78 10 f0 	movl   $0xf0107862,(%esp)
f01000d1:	e8 09 39 00 00       	call   f01039df <cprintf>
	va_end(ap);

dead:
	/* break into the kernel monitor */
	while (1)
		monitor(NULL);
f01000d6:	c7 04 24 00 00 00 00 	movl   $0x0,(%esp)
f01000dd:	e8 0e 09 00 00       	call   f01009f0 <monitor>
f01000e2:	eb f2                	jmp    f01000d6 <_panic+0x51>

f01000e4 <i386_init>:
#include <kern/pci.h>
#include <kern/monitor.h>

void
i386_init(void)
{
f01000e4:	55                   	push   %ebp
f01000e5:	89 e5                	mov    %esp,%ebp
f01000e7:	83 ec 18             	sub    $0x18,%esp
	extern char edata[], end[];

	// Before doing anything else, complete the ELF loading process.
	// Clear the uninitialized global data (BSS) section of our program.
	// This ensures that all static/global variables start out zero.
	memset(edata, 0, end - edata);
f01000ea:	b8 00 20 2d f0       	mov    $0xf02d2000,%eax
f01000ef:	2d 44 ed 2c f0       	sub    $0xf02ced44,%eax
f01000f4:	89 44 24 08          	mov    %eax,0x8(%esp)
f01000f8:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
f01000ff:	00 
f0100100:	c7 04 24 44 ed 2c f0 	movl   $0xf02ced44,(%esp)
f0100107:	e8 9a 59 00 00       	call   f0105aa6 <memset>

	// Initialize the console.
	// Can't call cprintf until after we do this!
	cons_init();
f010010c:	e8 ac 06 00 00       	call   f01007bd <cons_init>

	// Lab 2 memory management initialization functions
	i386_detect_memory();
f0100111:	e8 71 15 00 00       	call   f0101687 <i386_detect_memory>
	i386_vm_init();
f0100116:	e8 03 16 00 00       	call   f010171e <i386_vm_init>

	// Lab 3 user environment initialization functions
	env_init();
f010011b:	90                   	nop
f010011c:	8d 74 26 00          	lea    0x0(%esi,%eiz,1),%esi
f0100120:	e8 38 32 00 00       	call   f010335d <env_init>
	idt_init();
f0100125:	e8 e6 38 00 00       	call   f0103a10 <idt_init>

	// Lab 4 multitasking initialization functions
	pic_init();
f010012a:	e8 f1 37 00 00       	call   f0103920 <pic_init>
	kclock_init();
f010012f:	90                   	nop
f0100130:	e8 17 37 00 00       	call   f010384c <kclock_init>

	time_init();
f0100135:	e8 1a 65 00 00       	call   f0106654 <time_init>
	pci_init();
f010013a:	e8 f8 61 00 00       	call   f0106337 <pci_init>

	// Should always have an idle process as first one.
	ENV_CREATE(user_idle);
f010013f:	c7 44 24 04 13 42 01 	movl   $0x14213,0x4(%esp)
f0100146:	00 
f0100147:	c7 04 24 4d 36 13 f0 	movl   $0xf013364d,(%esp)
f010014e:	e8 76 35 00 00       	call   f01036c9 <env_create>

	// Start fs.
	ENV_CREATE(fs_fs);
f0100153:	c7 44 24 04 b4 e8 01 	movl   $0x1e8b4,0x4(%esp)
f010015a:	00 
f010015b:	c7 04 24 f3 29 23 f0 	movl   $0xf02329f3,(%esp)
f0100162:	e8 62 35 00 00       	call   f01036c9 <env_create>

#if !defined(TEST_NO_NS)
	// Start ns.
	ENV_CREATE(net_ns);
f0100167:	c7 44 24 04 76 02 05 	movl   $0x50276,0x4(%esp)
f010016e:	00 
f010016f:	c7 04 24 ce ea 27 f0 	movl   $0xf027eace,(%esp)
f0100176:	e8 4e 35 00 00       	call   f01036c9 <env_create>
	// Don't touch -- used by grading script!
	ENV_CREATE2(TEST, TESTSIZE);
#else
	// Touch all you want.
	//ENV_CREATE(user_testkbd);
	ENV_CREATE(user_primes);
f010017b:	c7 44 24 04 08 53 01 	movl   $0x15308,0x4(%esp)
f0100182:	00 
f0100183:	c7 04 24 50 cb 15 f0 	movl   $0xf015cb50,(%esp)
f010018a:	e8 3a 35 00 00       	call   f01036c9 <env_create>
#endif // TEST*

	// Should not be necessary - drains keyboard because interrupt has given up.
	kbd_intr();
f010018f:	e8 7b 00 00 00       	call   f010020f <kbd_intr>

	// Schedule and run the first user environment!
	sched_yield();
f0100194:	e8 f7 44 00 00       	call   f0104690 <sched_yield>
f0100199:	00 00                	add    %al,(%eax)
f010019b:	00 00                	add    %al,(%eax)
f010019d:	00 00                	add    %al,(%eax)
	...

f01001a0 <delay>:
static void cons_putc(int c);

// Stupid I/O delay routine necessitated by historical PC design flaws
static void
delay(void)
{
f01001a0:	55                   	push   %ebp
f01001a1:	89 e5                	mov    %esp,%ebp

static __inline uint8_t
inb(int port)
{
	uint8_t data;
	__asm __volatile("inb %w1,%0" : "=a" (data) : "d" (port));
f01001a3:	ba 84 00 00 00       	mov    $0x84,%edx
f01001a8:	ec                   	in     (%dx),%al
f01001a9:	ec                   	in     (%dx),%al
f01001aa:	ec                   	in     (%dx),%al
f01001ab:	ec                   	in     (%dx),%al
	inb(0x84);
	inb(0x84);
	inb(0x84);
	inb(0x84);
}
f01001ac:	5d                   	pop    %ebp
f01001ad:	c3                   	ret    

f01001ae <serial_proc_data>:

static bool serial_exists;

static int
serial_proc_data(void)
{
f01001ae:	55                   	push   %ebp
f01001af:	89 e5                	mov    %esp,%ebp
f01001b1:	ba fd 03 00 00       	mov    $0x3fd,%edx
f01001b6:	ec                   	in     (%dx),%al
f01001b7:	89 c2                	mov    %eax,%edx
	if (!(inb(COM1+COM_LSR) & COM_LSR_DATA))
f01001b9:	b8 ff ff ff ff       	mov    $0xffffffff,%eax
f01001be:	f6 c2 01             	test   $0x1,%dl
f01001c1:	74 09                	je     f01001cc <serial_proc_data+0x1e>
f01001c3:	ba f8 03 00 00       	mov    $0x3f8,%edx
f01001c8:	ec                   	in     (%dx),%al
		return -1;
	return inb(COM1+COM_RX);
f01001c9:	0f b6 c0             	movzbl %al,%eax
}
f01001cc:	5d                   	pop    %ebp
f01001cd:	c3                   	ret    

f01001ce <cons_intr>:

// called by device interrupt routines to feed input characters
// into the circular console input buffer.
static void
cons_intr(int (*proc)(void))
{
f01001ce:	55                   	push   %ebp
f01001cf:	89 e5                	mov    %esp,%ebp
f01001d1:	57                   	push   %edi
f01001d2:	56                   	push   %esi
f01001d3:	53                   	push   %ebx
f01001d4:	83 ec 0c             	sub    $0xc,%esp
f01001d7:	89 c6                	mov    %eax,%esi
	int c;

	while ((c = (*proc)()) != -1) {
		if (c == 0)
			continue;
		cons.buf[cons.wpos++] = c;
f01001d9:	bb 44 f2 2c f0       	mov    $0xf02cf244,%ebx
f01001de:	bf 40 f0 2c f0       	mov    $0xf02cf040,%edi
static void
cons_intr(int (*proc)(void))
{
	int c;

	while ((c = (*proc)()) != -1) {
f01001e3:	eb 1b                	jmp    f0100200 <cons_intr+0x32>
		if (c == 0)
f01001e5:	85 c0                	test   %eax,%eax
f01001e7:	74 17                	je     f0100200 <cons_intr+0x32>
			continue;
		cons.buf[cons.wpos++] = c;
f01001e9:	8b 13                	mov    (%ebx),%edx
f01001eb:	88 04 3a             	mov    %al,(%edx,%edi,1)
f01001ee:	8d 42 01             	lea    0x1(%edx),%eax
		if (cons.wpos == CONSBUFSIZE)
f01001f1:	3d 00 02 00 00       	cmp    $0x200,%eax
			cons.wpos = 0;
f01001f6:	ba 00 00 00 00       	mov    $0x0,%edx
f01001fb:	0f 44 c2             	cmove  %edx,%eax
f01001fe:	89 03                	mov    %eax,(%ebx)
static void
cons_intr(int (*proc)(void))
{
	int c;

	while ((c = (*proc)()) != -1) {
f0100200:	ff d6                	call   *%esi
f0100202:	83 f8 ff             	cmp    $0xffffffff,%eax
f0100205:	75 de                	jne    f01001e5 <cons_intr+0x17>
			continue;
		cons.buf[cons.wpos++] = c;
		if (cons.wpos == CONSBUFSIZE)
			cons.wpos = 0;
	}
}
f0100207:	83 c4 0c             	add    $0xc,%esp
f010020a:	5b                   	pop    %ebx
f010020b:	5e                   	pop    %esi
f010020c:	5f                   	pop    %edi
f010020d:	5d                   	pop    %ebp
f010020e:	c3                   	ret    

f010020f <kbd_intr>:
	return c;
}

void
kbd_intr(void)
{
f010020f:	55                   	push   %ebp
f0100210:	89 e5                	mov    %esp,%ebp
f0100212:	83 ec 08             	sub    $0x8,%esp
	cons_intr(kbd_proc_data);
f0100215:	b8 be 06 10 f0       	mov    $0xf01006be,%eax
f010021a:	e8 af ff ff ff       	call   f01001ce <cons_intr>
}
f010021f:	c9                   	leave  
f0100220:	c3                   	ret    

f0100221 <serial_intr>:
	return inb(COM1+COM_RX);
}

void
serial_intr(void)
{
f0100221:	55                   	push   %ebp
f0100222:	89 e5                	mov    %esp,%ebp
f0100224:	83 ec 08             	sub    $0x8,%esp
	if (serial_exists)
f0100227:	83 3d 2c f0 2c f0 00 	cmpl   $0x0,0xf02cf02c
f010022e:	74 0a                	je     f010023a <serial_intr+0x19>
		cons_intr(serial_proc_data);
f0100230:	b8 ae 01 10 f0       	mov    $0xf01001ae,%eax
f0100235:	e8 94 ff ff ff       	call   f01001ce <cons_intr>
}
f010023a:	c9                   	leave  
f010023b:	c3                   	ret    

f010023c <cons_getc>:
}

// return the next input character from the console, or 0 if none waiting
int
cons_getc(void)
{
f010023c:	55                   	push   %ebp
f010023d:	89 e5                	mov    %esp,%ebp
f010023f:	83 ec 08             	sub    $0x8,%esp
	int c;

	// poll for any pending input characters,
	// so that this function works even when interrupts are disabled
	// (e.g., when called from the kernel monitor).
	serial_intr();
f0100242:	e8 da ff ff ff       	call   f0100221 <serial_intr>
	kbd_intr();
f0100247:	e8 c3 ff ff ff       	call   f010020f <kbd_intr>

	// grab the next character from the input buffer.
	if (cons.rpos != cons.wpos) {
f010024c:	8b 15 40 f2 2c f0    	mov    0xf02cf240,%edx
f0100252:	b8 00 00 00 00       	mov    $0x0,%eax
f0100257:	3b 15 44 f2 2c f0    	cmp    0xf02cf244,%edx
f010025d:	74 1e                	je     f010027d <cons_getc+0x41>
		c = cons.buf[cons.rpos++];
f010025f:	0f b6 82 40 f0 2c f0 	movzbl -0xfd30fc0(%edx),%eax
f0100266:	83 c2 01             	add    $0x1,%edx
		if (cons.rpos == CONSBUFSIZE)
f0100269:	81 fa 00 02 00 00    	cmp    $0x200,%edx
			cons.rpos = 0;
f010026f:	b9 00 00 00 00       	mov    $0x0,%ecx
f0100274:	0f 44 d1             	cmove  %ecx,%edx
f0100277:	89 15 40 f2 2c f0    	mov    %edx,0xf02cf240
		return c;
	}
	return 0;
}
f010027d:	c9                   	leave  
f010027e:	c3                   	ret    

f010027f <getchar>:
	cons_putc(c);
}

int
getchar(void)
{
f010027f:	55                   	push   %ebp
f0100280:	89 e5                	mov    %esp,%ebp
f0100282:	83 ec 08             	sub    $0x8,%esp
	int c;

	while ((c = cons_getc()) == 0)
f0100285:	e8 b2 ff ff ff       	call   f010023c <cons_getc>
f010028a:	85 c0                	test   %eax,%eax
f010028c:	74 f7                	je     f0100285 <getchar+0x6>
		/* do nothing */;
	return c;
}
f010028e:	c9                   	leave  
f010028f:	c3                   	ret    

f0100290 <iscons>:

int
iscons(int fdnum)
{
f0100290:	55                   	push   %ebp
f0100291:	89 e5                	mov    %esp,%ebp
	// used by readline
	return 1;
}
f0100293:	b8 01 00 00 00       	mov    $0x1,%eax
f0100298:	5d                   	pop    %ebp
f0100299:	c3                   	ret    

f010029a <cga_putc>:
	crt_pos = pos;
}

static void
cga_putc(int c)
{
f010029a:	55                   	push   %ebp
f010029b:	89 e5                	mov    %esp,%ebp
f010029d:	57                   	push   %edi
f010029e:	56                   	push   %esi
f010029f:	53                   	push   %ebx
f01002a0:	83 ec 2c             	sub    $0x2c,%esp
    if (fmtPtr > 0) {
f01002a3:	8b 15 20 f0 2c f0    	mov    0xf02cf020,%edx
f01002a9:	85 d2                	test   %edx,%edx
f01002ab:	0f 8e bb 01 00 00    	jle    f010046c <cga_putc+0x1d2>
        if (c == '-') {
            // Validate template character.
            goto failCase;
        }
        while (skipIdx [fmtPtr] != -1 || (colorFmt [fmtPtr] == c || (colorFmt [fmtPtr] == '-' && c >= '0' && c <= '9'))) {
f01002b1:	bf 40 e0 11 f0       	mov    $0xf011e040,%edi

static void
cga_putc(int c)
{
    if (fmtPtr > 0) {
        if (c == '-') {
f01002b6:	83 f8 2d             	cmp    $0x2d,%eax
f01002b9:	0f 85 1c 01 00 00    	jne    f01003db <cga_putc+0x141>
f01002bf:	e9 65 01 00 00       	jmp    f0100429 <cga_putc+0x18f>
            // Validate template character.
            goto failCase;
        }
        while (skipIdx [fmtPtr] != -1 || (colorFmt [fmtPtr] == c || (colorFmt [fmtPtr] == '-' && c >= '0' && c <= '9'))) {
            if (colorFmt [fmtPtr] == c || (colorFmt [fmtPtr] == '-' && c >= '0' && c <= '9')) {
f01002c4:	0f b6 8a 20 e0 11 f0 	movzbl -0xfee1fe0(%edx),%ecx
f01002cb:	0f be f1             	movsbl %cl,%esi
f01002ce:	39 c6                	cmp    %eax,%esi
f01002d0:	75 08                	jne    f01002da <cga_putc+0x40>
f01002d2:	89 15 20 f0 2c f0    	mov    %edx,0xf02cf020
f01002d8:	eb 22                	jmp    f01002fc <cga_putc+0x62>
f01002da:	80 f9 2d             	cmp    $0x2d,%cl
f01002dd:	0f 85 f6 00 00 00    	jne    f01003d9 <cga_putc+0x13f>
f01002e3:	83 f8 2f             	cmp    $0x2f,%eax
f01002e6:	0f 8e ed 00 00 00    	jle    f01003d9 <cga_putc+0x13f>
f01002ec:	83 f8 39             	cmp    $0x39,%eax
f01002ef:	90                   	nop
f01002f0:	0f 8f e3 00 00 00    	jg     f01003d9 <cga_putc+0x13f>
f01002f6:	89 15 20 f0 2c f0    	mov    %edx,0xf02cf020
                printBuffer [bufferPtr++]   = c;
f01002fc:	8b 35 24 f0 2c f0    	mov    0xf02cf024,%esi
f0100302:	88 86 0c ff 2c f0    	mov    %al,-0xfd300f4(%esi)
f0100308:	83 c6 01             	add    $0x1,%esi
f010030b:	89 35 24 f0 2c f0    	mov    %esi,0xf02cf024
                fmtPtr++;
f0100311:	83 05 20 f0 2c f0 01 	addl   $0x1,0xf02cf020
                if (c == 'm') {
f0100318:	83 f8 6d             	cmp    $0x6d,%eax
f010031b:	0f 85 f4 02 00 00    	jne    f0100615 <cga_putc+0x37b>
                    int i   = 0;
                    int attributes [4];
                    int curAttrib   = 0;
                    for (i = 1; i < bufferPtr; i++) {
f0100321:	b0 00                	mov    $0x0,%al
f0100323:	ba 01 00 00 00       	mov    $0x1,%edx
                        if (printBuffer [i] >= '0' && printBuffer [i] <= '9') {
f0100328:	bf 0c ff 2c f0       	mov    $0xf02cff0c,%edi
                fmtPtr++;
                if (c == 'm') {
                    int i   = 0;
                    int attributes [4];
                    int curAttrib   = 0;
                    for (i = 1; i < bufferPtr; i++) {
f010032d:	83 fe 01             	cmp    $0x1,%esi
f0100330:	7f 0d                	jg     f010033f <cga_putc+0xa5>
f0100332:	8b 35 74 e0 11 f0    	mov    0xf011e074,%esi
f0100338:	ba 00 00 00 00       	mov    $0x0,%edx
f010033d:	eb 38                	jmp    f0100377 <cga_putc+0xdd>
                        if (printBuffer [i] >= '0' && printBuffer [i] <= '9') {
f010033f:	0f b6 0c 3a          	movzbl (%edx,%edi,1),%ecx
f0100343:	8d 59 d0             	lea    -0x30(%ecx),%ebx
f0100346:	80 fb 09             	cmp    $0x9,%bl
f0100349:	77 14                	ja     f010035f <cga_putc+0xc5>
                            attributes [curAttrib]  = attributes [curAttrib]*10 + printBuffer [i] - '0';
f010034b:	0f be c9             	movsbl %cl,%ecx
f010034e:	8b 5c 85 d8          	mov    -0x28(%ebp,%eax,4),%ebx
f0100352:	8d 1c 9b             	lea    (%ebx,%ebx,4),%ebx
f0100355:	8d 4c 59 d0          	lea    -0x30(%ecx,%ebx,2),%ecx
f0100359:	89 4c 85 d8          	mov    %ecx,-0x28(%ebp,%eax,4)
f010035d:	eb 0b                	jmp    f010036a <cga_putc+0xd0>
                        } else {
                            attributes [++curAttrib]    = 0;
f010035f:	83 c0 01             	add    $0x1,%eax
f0100362:	c7 44 85 d8 00 00 00 	movl   $0x0,-0x28(%ebp,%eax,4)
f0100369:	00 
                fmtPtr++;
                if (c == 'm') {
                    int i   = 0;
                    int attributes [4];
                    int curAttrib   = 0;
                    for (i = 1; i < bufferPtr; i++) {
f010036a:	83 c2 01             	add    $0x1,%edx
f010036d:	39 d6                	cmp    %edx,%esi
f010036f:	7f ce                	jg     f010033f <cga_putc+0xa5>
                        } else {
                            attributes [++curAttrib]    = 0;
                        }
                    }
                    //Assign Colors
                    for (i = 0; i <= curAttrib; i++) {
f0100371:	85 c0                	test   %eax,%eax
f0100373:	79 bd                	jns    f0100332 <cga_putc+0x98>
f0100375:	eb 49                	jmp    f01003c0 <cga_putc+0x126>
                        if (attributes [i] >= 30 && attributes [i] <= 37) {
f0100377:	8b 4c 95 d8          	mov    -0x28(%ebp,%edx,4),%ecx
f010037b:	89 cf                	mov    %ecx,%edi
f010037d:	8d 59 e2             	lea    -0x1e(%ecx),%ebx
f0100380:	83 fb 07             	cmp    $0x7,%ebx
f0100383:	77 14                	ja     f0100399 <cga_putc+0xff>
                            defColors   &= 0xF0FF;
f0100385:	81 e6 ff f0 00 00    	and    $0xf0ff,%esi
                            defColors   |= (colorIndices [attributes [i] - 30] << 8);
f010038b:	0f be 89 4e e0 11 f0 	movsbl -0xfee1fb2(%ecx),%ecx
f0100392:	c1 e1 08             	shl    $0x8,%ecx
f0100395:	09 ce                	or     %ecx,%esi
f0100397:	eb 1a                	jmp    f01003b3 <cga_putc+0x119>
                        } else if (attributes [i] >= 40 && attributes [i] <= 47) {
f0100399:	83 ef 28             	sub    $0x28,%edi
f010039c:	83 ff 07             	cmp    $0x7,%edi
f010039f:	77 12                	ja     f01003b3 <cga_putc+0x119>
                            defColors   &= 0x0FFF;
f01003a1:	81 e6 ff 0f 00 00    	and    $0xfff,%esi
                            defColors   |= (colorIndices [attributes [i] - 40] << 12);
f01003a7:	0f be 89 44 e0 11 f0 	movsbl -0xfee1fbc(%ecx),%ecx
f01003ae:	c1 e1 0c             	shl    $0xc,%ecx
f01003b1:	09 ce                	or     %ecx,%esi
                        } else {
                            attributes [++curAttrib]    = 0;
                        }
                    }
                    //Assign Colors
                    for (i = 0; i <= curAttrib; i++) {
f01003b3:	83 c2 01             	add    $0x1,%edx
f01003b6:	39 c2                	cmp    %eax,%edx
f01003b8:	7e bd                	jle    f0100377 <cga_putc+0xdd>
f01003ba:	89 35 74 e0 11 f0    	mov    %esi,0xf011e074
                            defColors   &= 0x0FFF;
                            defColors   |= (colorIndices [attributes [i] - 40] << 12);
                        }
                    }

                    fmtPtr      = 0;
f01003c0:	c7 05 20 f0 2c f0 00 	movl   $0x0,0xf02cf020
f01003c7:	00 00 00 
                    bufferPtr   = 0;
f01003ca:	c7 05 24 f0 2c f0 00 	movl   $0x0,0xf02cf024
f01003d1:	00 00 00 
f01003d4:	e9 3c 02 00 00       	jmp    f0100615 <cga_putc+0x37b>
f01003d9:	89 da                	mov    %ebx,%edx
    if (fmtPtr > 0) {
        if (c == '-') {
            // Validate template character.
            goto failCase;
        }
        while (skipIdx [fmtPtr] != -1 || (colorFmt [fmtPtr] == c || (colorFmt [fmtPtr] == '-' && c >= '0' && c <= '9'))) {
f01003db:	8b 1c 97             	mov    (%edi,%edx,4),%ebx
f01003de:	83 fb ff             	cmp    $0xffffffff,%ebx
f01003e1:	0f 85 dd fe ff ff    	jne    f01002c4 <cga_putc+0x2a>
f01003e7:	0f b6 8a 20 e0 11 f0 	movzbl -0xfee1fe0(%edx),%ecx
f01003ee:	0f be f1             	movsbl %cl,%esi
f01003f1:	39 c6                	cmp    %eax,%esi
f01003f3:	75 0b                	jne    f0100400 <cga_putc+0x166>
f01003f5:	89 15 20 f0 2c f0    	mov    %edx,0xf02cf020
f01003fb:	e9 fc fe ff ff       	jmp    f01002fc <cga_putc+0x62>
f0100400:	80 f9 2d             	cmp    $0x2d,%cl
f0100403:	75 05                	jne    f010040a <cga_putc+0x170>
f0100405:	83 f8 2f             	cmp    $0x2f,%eax
f0100408:	7f 08                	jg     f0100412 <cga_putc+0x178>
f010040a:	89 15 20 f0 2c f0    	mov    %edx,0xf02cf020
f0100410:	eb 0f                	jmp    f0100421 <cga_putc+0x187>
f0100412:	83 f8 39             	cmp    $0x39,%eax
f0100415:	0f 8e bf fe ff ff    	jle    f01002da <cga_putc+0x40>
f010041b:	89 15 20 f0 2c f0    	mov    %edx,0xf02cf020
            } else {
                fmtPtr  = skipIdx [fmtPtr];
            }
        }

        if (fmtPtr != 0 && skipIdx [fmtPtr] == -1) {
f0100421:	85 d2                	test   %edx,%edx
f0100423:	0f 84 ec 01 00 00    	je     f0100615 <cga_putc+0x37b>
            // Error case.
            //Flush to output.
failCase:
            printBuffer [bufferPtr++]   = c;
f0100429:	8b 15 24 f0 2c f0    	mov    0xf02cf024,%edx
f010042f:	88 82 0c ff 2c f0    	mov    %al,-0xfd300f4(%edx)
f0100435:	83 c2 01             	add    $0x1,%edx
f0100438:	89 15 24 f0 2c f0    	mov    %edx,0xf02cf024
            fmtPtr                  = 0;
f010043e:	c7 05 20 f0 2c f0 00 	movl   $0x0,0xf02cf020
f0100445:	00 00 00 
            crt_buf[crt_pos++]      = '\e';		/* write the character */
f0100448:	0f b7 05 38 f0 2c f0 	movzwl 0xf02cf038,%eax
f010044f:	0f b7 c8             	movzwl %ax,%ecx
f0100452:	8b 15 34 f0 2c f0    	mov    0xf02cf034,%edx
f0100458:	66 c7 04 4a 1b 00    	movw   $0x1b,(%edx,%ecx,2)
f010045e:	83 c0 01             	add    $0x1,%eax
f0100461:	66 a3 38 f0 2c f0    	mov    %ax,0xf02cf038
            goto printEscape;
f0100467:	e9 f2 00 00 00       	jmp    f010055e <cga_putc+0x2c4>
        }
    }

	// if no attribute given, then use black on white
	if (!(c & ~0xFF))
		c |= defColors;
f010046c:	89 c2                	mov    %eax,%edx
f010046e:	0b 15 74 e0 11 f0    	or     0xf011e074,%edx
f0100474:	a9 00 ff ff ff       	test   $0xffffff00,%eax
f0100479:	0f 44 c2             	cmove  %edx,%eax

	switch (c & 0xff) {
f010047c:	0f b6 d0             	movzbl %al,%edx
f010047f:	83 ea 08             	sub    $0x8,%edx
f0100482:	83 fa 13             	cmp    $0x13,%edx
f0100485:	0f 87 b5 00 00 00    	ja     f0100540 <cga_putc+0x2a6>
f010048b:	ff 24 95 60 69 10 f0 	jmp    *-0xfef96a0(,%edx,4)
	case '\b':
		if (crt_pos > 0) {
f0100492:	0f b7 15 38 f0 2c f0 	movzwl 0xf02cf038,%edx
f0100499:	66 85 d2             	test   %dx,%dx
f010049c:	0f 84 10 01 00 00    	je     f01005b2 <cga_putc+0x318>
			crt_pos--;
f01004a2:	83 ea 01             	sub    $0x1,%edx
f01004a5:	66 89 15 38 f0 2c f0 	mov    %dx,0xf02cf038
			crt_buf[crt_pos] = (c & ~0xff) | ' ';
f01004ac:	0f b7 d2             	movzwl %dx,%edx
f01004af:	b0 00                	mov    $0x0,%al
f01004b1:	89 c1                	mov    %eax,%ecx
f01004b3:	83 c9 20             	or     $0x20,%ecx
f01004b6:	a1 34 f0 2c f0       	mov    0xf02cf034,%eax
f01004bb:	66 89 0c 50          	mov    %cx,(%eax,%edx,2)
f01004bf:	e9 9a 00 00 00       	jmp    f010055e <cga_putc+0x2c4>
		}
		break;
	case '\n':
		crt_pos += CRT_COLS;
f01004c4:	66 83 05 38 f0 2c f0 	addw   $0x50,0xf02cf038
f01004cb:	50 
		/* fallthru */
	case '\r':
		crt_pos -= (crt_pos % CRT_COLS);
f01004cc:	0f b7 05 38 f0 2c f0 	movzwl 0xf02cf038,%eax
f01004d3:	69 c0 cd cc 00 00    	imul   $0xcccd,%eax,%eax
f01004d9:	c1 e8 10             	shr    $0x10,%eax
f01004dc:	66 c1 e8 06          	shr    $0x6,%ax
f01004e0:	8d 04 80             	lea    (%eax,%eax,4),%eax
f01004e3:	c1 e0 04             	shl    $0x4,%eax
f01004e6:	66 a3 38 f0 2c f0    	mov    %ax,0xf02cf038
		break;
f01004ec:	eb 70                	jmp    f010055e <cga_putc+0x2c4>
	case '\t':
		cons_putc(' ');
f01004ee:	b8 20 00 00 00       	mov    $0x20,%eax
f01004f3:	e8 25 01 00 00       	call   f010061d <cons_putc>
		cons_putc(' ');
f01004f8:	b8 20 00 00 00       	mov    $0x20,%eax
f01004fd:	e8 1b 01 00 00       	call   f010061d <cons_putc>
		cons_putc(' ');
f0100502:	b8 20 00 00 00       	mov    $0x20,%eax
f0100507:	e8 11 01 00 00       	call   f010061d <cons_putc>
		cons_putc(' ');
f010050c:	b8 20 00 00 00       	mov    $0x20,%eax
f0100511:	e8 07 01 00 00       	call   f010061d <cons_putc>
		cons_putc(' ');
f0100516:	b8 20 00 00 00       	mov    $0x20,%eax
f010051b:	e8 fd 00 00 00       	call   f010061d <cons_putc>
		break;
f0100520:	eb 3c                	jmp    f010055e <cga_putc+0x2c4>
    case '\e':
        bufferPtr       = 0;
        fmtPtr          = 1;
f0100522:	c7 05 20 f0 2c f0 01 	movl   $0x1,0xf02cf020
f0100529:	00 00 00 
        printBuffer [bufferPtr++]   = c;
f010052c:	a2 0c ff 2c f0       	mov    %al,0xf02cff0c
f0100531:	c7 05 24 f0 2c f0 01 	movl   $0x1,0xf02cf024
f0100538:	00 00 00 
        return;
f010053b:	e9 d5 00 00 00       	jmp    f0100615 <cga_putc+0x37b>
	default:
		crt_buf[crt_pos++] = c;		/* write the character */
f0100540:	0f b7 15 38 f0 2c f0 	movzwl 0xf02cf038,%edx
f0100547:	0f b7 da             	movzwl %dx,%ebx
f010054a:	8b 0d 34 f0 2c f0    	mov    0xf02cf034,%ecx
f0100550:	66 89 04 59          	mov    %ax,(%ecx,%ebx,2)
f0100554:	83 c2 01             	add    $0x1,%edx
f0100557:	66 89 15 38 f0 2c f0 	mov    %dx,0xf02cf038

printEscape:
	// If the screen is full, it scrolls up by a row.
	// This erases the top row and give a new row at the bottom.

	if (crt_pos >= CRT_SIZE) {
f010055e:	66 81 3d 38 f0 2c f0 	cmpw   $0x7cf,0xf02cf038
f0100565:	cf 07 
f0100567:	76 49                	jbe    f01005b2 <cga_putc+0x318>
		int i;

		memmove(crt_buf, crt_buf + CRT_COLS, (CRT_SIZE - CRT_COLS) * sizeof(uint16_t));
f0100569:	a1 34 f0 2c f0       	mov    0xf02cf034,%eax
f010056e:	c7 44 24 08 00 0f 00 	movl   $0xf00,0x8(%esp)
f0100575:	00 
f0100576:	8d 90 a0 00 00 00    	lea    0xa0(%eax),%edx
f010057c:	89 54 24 04          	mov    %edx,0x4(%esp)
f0100580:	89 04 24             	mov    %eax,(%esp)
f0100583:	e8 7d 55 00 00       	call   f0105b05 <memmove>
f0100588:	b8 00 0f 00 00       	mov    $0xf00,%eax
		for (i = CRT_SIZE - CRT_COLS; i < CRT_SIZE; i++)
			crt_buf[i] = defColors | ' ';
f010058d:	8b 0d 74 e0 11 f0    	mov    0xf011e074,%ecx
f0100593:	83 c9 20             	or     $0x20,%ecx
f0100596:	8b 15 34 f0 2c f0    	mov    0xf02cf034,%edx
f010059c:	66 89 0c 02          	mov    %cx,(%edx,%eax,1)
f01005a0:	83 c0 02             	add    $0x2,%eax

	if (crt_pos >= CRT_SIZE) {
		int i;

		memmove(crt_buf, crt_buf + CRT_COLS, (CRT_SIZE - CRT_COLS) * sizeof(uint16_t));
		for (i = CRT_SIZE - CRT_COLS; i < CRT_SIZE; i++)
f01005a3:	3d a0 0f 00 00       	cmp    $0xfa0,%eax
f01005a8:	75 e3                	jne    f010058d <cga_putc+0x2f3>
			crt_buf[i] = defColors | ' ';
		crt_pos -= CRT_COLS;
f01005aa:	66 83 2d 38 f0 2c f0 	subw   $0x50,0xf02cf038
f01005b1:	50 
	}

	/* move that little blinky thing */
	outb(addr_6845, 14);
f01005b2:	8b 0d 30 f0 2c f0    	mov    0xf02cf030,%ecx
f01005b8:	89 cb                	mov    %ecx,%ebx
}

static __inline void
outb(int port, uint8_t data)
{
	__asm __volatile("outb %0,%w1" : : "a" (data), "d" (port));
f01005ba:	b8 0e 00 00 00       	mov    $0xe,%eax
f01005bf:	89 ca                	mov    %ecx,%edx
f01005c1:	ee                   	out    %al,(%dx)
	outb(addr_6845 + 1, crt_pos >> 8);
f01005c2:	0f b7 35 38 f0 2c f0 	movzwl 0xf02cf038,%esi
f01005c9:	83 c1 01             	add    $0x1,%ecx
f01005cc:	89 f0                	mov    %esi,%eax
f01005ce:	66 c1 e8 08          	shr    $0x8,%ax
f01005d2:	89 ca                	mov    %ecx,%edx
f01005d4:	ee                   	out    %al,(%dx)
f01005d5:	b8 0f 00 00 00       	mov    $0xf,%eax
f01005da:	89 da                	mov    %ebx,%edx
f01005dc:	ee                   	out    %al,(%dx)
f01005dd:	89 f0                	mov    %esi,%eax
f01005df:	89 ca                	mov    %ecx,%edx
f01005e1:	ee                   	out    %al,(%dx)
	outb(addr_6845, 15);
	outb(addr_6845 + 1, crt_pos);

    if (bufferPtr > 0) {
f01005e2:	8b 3d 24 f0 2c f0    	mov    0xf02cf024,%edi
f01005e8:	85 ff                	test   %edi,%edi
f01005ea:	7e 29                	jle    f0100615 <cga_putc+0x37b>
        int count   = bufferPtr;
        int i;
        bufferPtr   = 0;
f01005ec:	c7 05 24 f0 2c f0 00 	movl   $0x0,0xf02cf024
f01005f3:	00 00 00 
        for(i = 1; i < count ; i++) {
f01005f6:	83 ff 01             	cmp    $0x1,%edi
f01005f9:	7e 1a                	jle    f0100615 <cga_putc+0x37b>
f01005fb:	bb 01 00 00 00       	mov    $0x1,%ebx
            cga_putc(printBuffer [i]);
f0100600:	be 0c ff 2c f0       	mov    $0xf02cff0c,%esi
f0100605:	0f be 04 33          	movsbl (%ebx,%esi,1),%eax
f0100609:	e8 8c fc ff ff       	call   f010029a <cga_putc>

    if (bufferPtr > 0) {
        int count   = bufferPtr;
        int i;
        bufferPtr   = 0;
        for(i = 1; i < count ; i++) {
f010060e:	83 c3 01             	add    $0x1,%ebx
f0100611:	39 df                	cmp    %ebx,%edi
f0100613:	7f f0                	jg     f0100605 <cga_putc+0x36b>
            cga_putc(printBuffer [i]);
        }
    }
}
f0100615:	83 c4 2c             	add    $0x2c,%esp
f0100618:	5b                   	pop    %ebx
f0100619:	5e                   	pop    %esi
f010061a:	5f                   	pop    %edi
f010061b:	5d                   	pop    %ebp
f010061c:	c3                   	ret    

f010061d <cons_putc>:
}

// output a character to the console
static void
cons_putc(int c)
{
f010061d:	55                   	push   %ebp
f010061e:	89 e5                	mov    %esp,%ebp
f0100620:	57                   	push   %edi
f0100621:	56                   	push   %esi
f0100622:	53                   	push   %ebx
f0100623:	83 ec 1c             	sub    $0x1c,%esp
f0100626:	89 45 e4             	mov    %eax,-0x1c(%ebp)

static __inline uint8_t
inb(int port)
{
	uint8_t data;
	__asm __volatile("inb %w1,%0" : "=a" (data) : "d" (port));
f0100629:	ba fd 03 00 00       	mov    $0x3fd,%edx
f010062e:	ec                   	in     (%dx),%al
static void
serial_putc(int c)
{
	int i;
	
	for (i = 0;
f010062f:	a8 20                	test   $0x20,%al
f0100631:	75 21                	jne    f0100654 <cons_putc+0x37>
f0100633:	bb 00 00 00 00       	mov    $0x0,%ebx
f0100638:	be fd 03 00 00       	mov    $0x3fd,%esi
	     !(inb(COM1 + COM_LSR) & COM_LSR_TXRDY) && i < 12800;
	     i++)
		delay();
f010063d:	e8 5e fb ff ff       	call   f01001a0 <delay>
f0100642:	89 f2                	mov    %esi,%edx
f0100644:	ec                   	in     (%dx),%al
static void
serial_putc(int c)
{
	int i;
	
	for (i = 0;
f0100645:	a8 20                	test   $0x20,%al
f0100647:	75 0b                	jne    f0100654 <cons_putc+0x37>
	     !(inb(COM1 + COM_LSR) & COM_LSR_TXRDY) && i < 12800;
	     i++)
f0100649:	83 c3 01             	add    $0x1,%ebx
static void
serial_putc(int c)
{
	int i;
	
	for (i = 0;
f010064c:	81 fb 00 32 00 00    	cmp    $0x3200,%ebx
f0100652:	75 e9                	jne    f010063d <cons_putc+0x20>
	     !(inb(COM1 + COM_LSR) & COM_LSR_TXRDY) && i < 12800;
	     i++)
		delay();
	
	outb(COM1 + COM_TX, c);
f0100654:	0f b6 7d e4          	movzbl -0x1c(%ebp),%edi
}

static __inline void
outb(int port, uint8_t data)
{
	__asm __volatile("outb %0,%w1" : : "a" (data), "d" (port));
f0100658:	ba f8 03 00 00       	mov    $0x3f8,%edx
f010065d:	89 f8                	mov    %edi,%eax
f010065f:	ee                   	out    %al,(%dx)

static __inline uint8_t
inb(int port)
{
	uint8_t data;
	__asm __volatile("inb %w1,%0" : "=a" (data) : "d" (port));
f0100660:	b2 79                	mov    $0x79,%dl
f0100662:	ec                   	in     (%dx),%al
static void
lpt_putc(int c)
{
	int i;

	for (i = 0; !(inb(0x378+1) & 0x80) && i < 12800; i++)
f0100663:	84 c0                	test   %al,%al
f0100665:	78 21                	js     f0100688 <cons_putc+0x6b>
f0100667:	bb 00 00 00 00       	mov    $0x0,%ebx
f010066c:	be 79 03 00 00       	mov    $0x379,%esi
		delay();
f0100671:	e8 2a fb ff ff       	call   f01001a0 <delay>
f0100676:	89 f2                	mov    %esi,%edx
f0100678:	ec                   	in     (%dx),%al
static void
lpt_putc(int c)
{
	int i;

	for (i = 0; !(inb(0x378+1) & 0x80) && i < 12800; i++)
f0100679:	84 c0                	test   %al,%al
f010067b:	78 0b                	js     f0100688 <cons_putc+0x6b>
f010067d:	83 c3 01             	add    $0x1,%ebx
f0100680:	81 fb 00 32 00 00    	cmp    $0x3200,%ebx
f0100686:	75 e9                	jne    f0100671 <cons_putc+0x54>
}

static __inline void
outb(int port, uint8_t data)
{
	__asm __volatile("outb %0,%w1" : : "a" (data), "d" (port));
f0100688:	ba 78 03 00 00       	mov    $0x378,%edx
f010068d:	89 f8                	mov    %edi,%eax
f010068f:	ee                   	out    %al,(%dx)
f0100690:	b2 7a                	mov    $0x7a,%dl
f0100692:	b8 0d 00 00 00       	mov    $0xd,%eax
f0100697:	ee                   	out    %al,(%dx)
f0100698:	b8 08 00 00 00       	mov    $0x8,%eax
f010069d:	ee                   	out    %al,(%dx)
static void
cons_putc(int c)
{
	serial_putc(c);
	lpt_putc(c);
	cga_putc(c);
f010069e:	8b 45 e4             	mov    -0x1c(%ebp),%eax
f01006a1:	e8 f4 fb ff ff       	call   f010029a <cga_putc>
}
f01006a6:	83 c4 1c             	add    $0x1c,%esp
f01006a9:	5b                   	pop    %ebx
f01006aa:	5e                   	pop    %esi
f01006ab:	5f                   	pop    %edi
f01006ac:	5d                   	pop    %ebp
f01006ad:	c3                   	ret    

f01006ae <cputchar>:

// `High'-level console I/O.  Used by readline and cprintf.

void
cputchar(int c)
{
f01006ae:	55                   	push   %ebp
f01006af:	89 e5                	mov    %esp,%ebp
f01006b1:	83 ec 08             	sub    $0x8,%esp
	cons_putc(c);
f01006b4:	8b 45 08             	mov    0x8(%ebp),%eax
f01006b7:	e8 61 ff ff ff       	call   f010061d <cons_putc>
}
f01006bc:	c9                   	leave  
f01006bd:	c3                   	ret    

f01006be <kbd_proc_data>:
 * Get data from the keyboard.  If we finish a character, return it.  Else 0.
 * Return -1 if no data.
 */
static int
kbd_proc_data(void)
{
f01006be:	55                   	push   %ebp
f01006bf:	89 e5                	mov    %esp,%ebp
f01006c1:	53                   	push   %ebx
f01006c2:	83 ec 14             	sub    $0x14,%esp

static __inline uint8_t
inb(int port)
{
	uint8_t data;
	__asm __volatile("inb %w1,%0" : "=a" (data) : "d" (port));
f01006c5:	ba 64 00 00 00       	mov    $0x64,%edx
f01006ca:	ec                   	in     (%dx),%al
	int c;
	uint8_t data;
	static uint32_t shift;

	if ((inb(KBSTATP) & KBS_DIB) == 0)
f01006cb:	bb ff ff ff ff       	mov    $0xffffffff,%ebx
f01006d0:	a8 01                	test   $0x1,%al
f01006d2:	0f 84 dd 00 00 00    	je     f01007b5 <kbd_proc_data+0xf7>
f01006d8:	b2 60                	mov    $0x60,%dl
f01006da:	ec                   	in     (%dx),%al
		return -1;

	data = inb(KBDATAP);

	if (data == 0xE0) {
f01006db:	3c e0                	cmp    $0xe0,%al
f01006dd:	75 11                	jne    f01006f0 <kbd_proc_data+0x32>
		// E0 escape character
		shift |= E0ESC;
f01006df:	83 0d 28 f0 2c f0 40 	orl    $0x40,0xf02cf028
f01006e6:	bb 00 00 00 00       	mov    $0x0,%ebx
		return 0;
f01006eb:	e9 c5 00 00 00       	jmp    f01007b5 <kbd_proc_data+0xf7>
	} else if (data & 0x80) {
f01006f0:	84 c0                	test   %al,%al
f01006f2:	79 35                	jns    f0100729 <kbd_proc_data+0x6b>
		// Key released
		data = (shift & E0ESC ? data : data & 0x7F);
f01006f4:	8b 15 28 f0 2c f0    	mov    0xf02cf028,%edx
f01006fa:	89 c1                	mov    %eax,%ecx
f01006fc:	83 e1 7f             	and    $0x7f,%ecx
f01006ff:	f6 c2 40             	test   $0x40,%dl
f0100702:	0f 44 c1             	cmove  %ecx,%eax
		shift &= ~(shiftcode[data] | E0ESC);
f0100705:	0f b6 c0             	movzbl %al,%eax
f0100708:	0f b6 80 c0 69 10 f0 	movzbl -0xfef9640(%eax),%eax
f010070f:	83 c8 40             	or     $0x40,%eax
f0100712:	0f b6 c0             	movzbl %al,%eax
f0100715:	f7 d0                	not    %eax
f0100717:	21 c2                	and    %eax,%edx
f0100719:	89 15 28 f0 2c f0    	mov    %edx,0xf02cf028
f010071f:	bb 00 00 00 00       	mov    $0x0,%ebx
		return 0;
f0100724:	e9 8c 00 00 00       	jmp    f01007b5 <kbd_proc_data+0xf7>
	} else if (shift & E0ESC) {
f0100729:	8b 15 28 f0 2c f0    	mov    0xf02cf028,%edx
f010072f:	f6 c2 40             	test   $0x40,%dl
f0100732:	74 0c                	je     f0100740 <kbd_proc_data+0x82>
		// Last character was an E0 escape; or with 0x80
		data |= 0x80;
f0100734:	83 c8 80             	or     $0xffffff80,%eax
		shift &= ~E0ESC;
f0100737:	83 e2 bf             	and    $0xffffffbf,%edx
f010073a:	89 15 28 f0 2c f0    	mov    %edx,0xf02cf028
	}

	shift |= shiftcode[data];
f0100740:	0f b6 c0             	movzbl %al,%eax
	shift ^= togglecode[data];
f0100743:	0f b6 90 c0 69 10 f0 	movzbl -0xfef9640(%eax),%edx
f010074a:	0b 15 28 f0 2c f0    	or     0xf02cf028,%edx
f0100750:	0f b6 88 c0 6a 10 f0 	movzbl -0xfef9540(%eax),%ecx
f0100757:	31 ca                	xor    %ecx,%edx
f0100759:	89 15 28 f0 2c f0    	mov    %edx,0xf02cf028

	c = charcode[shift & (CTL | SHIFT)][data];
f010075f:	89 d1                	mov    %edx,%ecx
f0100761:	83 e1 03             	and    $0x3,%ecx
f0100764:	8b 0c 8d c0 6b 10 f0 	mov    -0xfef9440(,%ecx,4),%ecx
f010076b:	0f b6 1c 01          	movzbl (%ecx,%eax,1),%ebx
	if (shift & CAPSLOCK) {
f010076f:	f6 c2 08             	test   $0x8,%dl
f0100772:	74 1b                	je     f010078f <kbd_proc_data+0xd1>
		if ('a' <= c && c <= 'z')
f0100774:	89 d9                	mov    %ebx,%ecx
f0100776:	8d 43 9f             	lea    -0x61(%ebx),%eax
f0100779:	83 f8 19             	cmp    $0x19,%eax
f010077c:	77 05                	ja     f0100783 <kbd_proc_data+0xc5>
			c += 'A' - 'a';
f010077e:	83 eb 20             	sub    $0x20,%ebx
f0100781:	eb 0c                	jmp    f010078f <kbd_proc_data+0xd1>
		else if ('A' <= c && c <= 'Z')
f0100783:	83 e9 41             	sub    $0x41,%ecx
			c += 'a' - 'A';
f0100786:	8d 43 20             	lea    0x20(%ebx),%eax
f0100789:	83 f9 19             	cmp    $0x19,%ecx
f010078c:	0f 46 d8             	cmovbe %eax,%ebx
	}

	// Process special keys
	// Ctrl-Alt-Del: reboot
	if (!(~shift & (CTL | ALT)) && c == KEY_DEL) {
f010078f:	f7 d2                	not    %edx
f0100791:	f6 c2 06             	test   $0x6,%dl
f0100794:	75 1f                	jne    f01007b5 <kbd_proc_data+0xf7>
f0100796:	81 fb e9 00 00 00    	cmp    $0xe9,%ebx
f010079c:	75 17                	jne    f01007b5 <kbd_proc_data+0xf7>
		cprintf("Rebooting!\n");
f010079e:	c7 04 24 d0 6b 10 f0 	movl   $0xf0106bd0,(%esp)
f01007a5:	e8 35 32 00 00       	call   f01039df <cprintf>
}

static __inline void
outb(int port, uint8_t data)
{
	__asm __volatile("outb %0,%w1" : : "a" (data), "d" (port));
f01007aa:	ba 92 00 00 00       	mov    $0x92,%edx
f01007af:	b8 03 00 00 00       	mov    $0x3,%eax
f01007b4:	ee                   	out    %al,(%dx)
		outb(0x92, 0x3); // courtesy of Chris Frost
	}

	return c;
}
f01007b5:	89 d8                	mov    %ebx,%eax
f01007b7:	83 c4 14             	add    $0x14,%esp
f01007ba:	5b                   	pop    %ebx
f01007bb:	5d                   	pop    %ebp
f01007bc:	c3                   	ret    

f01007bd <cons_init>:
}

// initialize the console devices
void
cons_init(void)
{
f01007bd:	55                   	push   %ebp
f01007be:	89 e5                	mov    %esp,%ebp
f01007c0:	57                   	push   %edi
f01007c1:	56                   	push   %esi
f01007c2:	53                   	push   %ebx
f01007c3:	83 ec 1c             	sub    $0x1c,%esp
	volatile uint16_t *cp;
	uint16_t was;
	unsigned pos;

	cp = (uint16_t*) (KERNBASE + CGA_BUF);
	was = *cp;
f01007c6:	b8 00 80 0b f0       	mov    $0xf00b8000,%eax
f01007cb:	0f b7 10             	movzwl (%eax),%edx
	*cp = (uint16_t) 0xA55A;
f01007ce:	66 c7 00 5a a5       	movw   $0xa55a,(%eax)
	if (*cp != 0xA55A) {
f01007d3:	0f b7 00             	movzwl (%eax),%eax
f01007d6:	66 3d 5a a5          	cmp    $0xa55a,%ax
f01007da:	74 11                	je     f01007ed <cons_init+0x30>
		cp = (uint16_t*) (KERNBASE + MONO_BUF);
		addr_6845 = MONO_BASE;
f01007dc:	c7 05 30 f0 2c f0 b4 	movl   $0x3b4,0xf02cf030
f01007e3:	03 00 00 
f01007e6:	be 00 00 0b f0       	mov    $0xf00b0000,%esi
f01007eb:	eb 16                	jmp    f0100803 <cons_init+0x46>
	} else {
		*cp = was;
f01007ed:	66 89 15 00 80 0b f0 	mov    %dx,0xf00b8000
		addr_6845 = CGA_BASE;
f01007f4:	c7 05 30 f0 2c f0 d4 	movl   $0x3d4,0xf02cf030
f01007fb:	03 00 00 
f01007fe:	be 00 80 0b f0       	mov    $0xf00b8000,%esi
	}
	
	/* Extract cursor location */
	outb(addr_6845, 14);
f0100803:	8b 0d 30 f0 2c f0    	mov    0xf02cf030,%ecx
f0100809:	89 cb                	mov    %ecx,%ebx
f010080b:	b8 0e 00 00 00       	mov    $0xe,%eax
f0100810:	89 ca                	mov    %ecx,%edx
f0100812:	ee                   	out    %al,(%dx)
	pos = inb(addr_6845 + 1) << 8;
f0100813:	83 c1 01             	add    $0x1,%ecx

static __inline uint8_t
inb(int port)
{
	uint8_t data;
	__asm __volatile("inb %w1,%0" : "=a" (data) : "d" (port));
f0100816:	89 ca                	mov    %ecx,%edx
f0100818:	ec                   	in     (%dx),%al
f0100819:	0f b6 f8             	movzbl %al,%edi
f010081c:	c1 e7 08             	shl    $0x8,%edi
}

static __inline void
outb(int port, uint8_t data)
{
	__asm __volatile("outb %0,%w1" : : "a" (data), "d" (port));
f010081f:	b8 0f 00 00 00       	mov    $0xf,%eax
f0100824:	89 da                	mov    %ebx,%edx
f0100826:	ee                   	out    %al,(%dx)

static __inline uint8_t
inb(int port)
{
	uint8_t data;
	__asm __volatile("inb %w1,%0" : "=a" (data) : "d" (port));
f0100827:	89 ca                	mov    %ecx,%edx
f0100829:	ec                   	in     (%dx),%al
	outb(addr_6845, 15);
	pos |= inb(addr_6845 + 1);

	crt_buf = (uint16_t*) cp;
f010082a:	89 35 34 f0 2c f0    	mov    %esi,0xf02cf034
	crt_pos = pos;
f0100830:	0f b6 c8             	movzbl %al,%ecx
f0100833:	09 cf                	or     %ecx,%edi
f0100835:	66 89 3d 38 f0 2c f0 	mov    %di,0xf02cf038

static void
kbd_init(void)
{
	// Drain the kbd buffer so that Bochs generates interrupts.
	kbd_intr();
f010083c:	e8 ce f9 ff ff       	call   f010020f <kbd_intr>
	irq_setmask_8259A(irq_mask_8259A & ~(1<<1));
f0100841:	0f b7 05 b8 e3 11 f0 	movzwl 0xf011e3b8,%eax
f0100848:	25 fd ff 00 00       	and    $0xfffd,%eax
f010084d:	89 04 24             	mov    %eax,(%esp)
f0100850:	e8 5a 30 00 00       	call   f01038af <irq_setmask_8259A>
}

static __inline void
outb(int port, uint8_t data)
{
	__asm __volatile("outb %0,%w1" : : "a" (data), "d" (port));
f0100855:	bb fa 03 00 00       	mov    $0x3fa,%ebx
f010085a:	b8 00 00 00 00       	mov    $0x0,%eax
f010085f:	89 da                	mov    %ebx,%edx
f0100861:	ee                   	out    %al,(%dx)
f0100862:	b2 fb                	mov    $0xfb,%dl
f0100864:	b8 80 ff ff ff       	mov    $0xffffff80,%eax
f0100869:	ee                   	out    %al,(%dx)
f010086a:	b9 f8 03 00 00       	mov    $0x3f8,%ecx
f010086f:	b8 0c 00 00 00       	mov    $0xc,%eax
f0100874:	89 ca                	mov    %ecx,%edx
f0100876:	ee                   	out    %al,(%dx)
f0100877:	b2 f9                	mov    $0xf9,%dl
f0100879:	b8 00 00 00 00       	mov    $0x0,%eax
f010087e:	ee                   	out    %al,(%dx)
f010087f:	b2 fb                	mov    $0xfb,%dl
f0100881:	b8 03 00 00 00       	mov    $0x3,%eax
f0100886:	ee                   	out    %al,(%dx)
f0100887:	b2 fc                	mov    $0xfc,%dl
f0100889:	b8 00 00 00 00       	mov    $0x0,%eax
f010088e:	ee                   	out    %al,(%dx)
f010088f:	b2 f9                	mov    $0xf9,%dl
f0100891:	b8 01 00 00 00       	mov    $0x1,%eax
f0100896:	ee                   	out    %al,(%dx)

static __inline uint8_t
inb(int port)
{
	uint8_t data;
	__asm __volatile("inb %w1,%0" : "=a" (data) : "d" (port));
f0100897:	b2 fd                	mov    $0xfd,%dl
f0100899:	ec                   	in     (%dx),%al
	// Enable rcv interrupts
	outb(COM1+COM_IER, COM_IER_RDI);

	// Clear any preexisting overrun indications and interrupts
	// Serial port doesn't exist if COM_LSR returns 0xFF
	serial_exists = (inb(COM1+COM_LSR) != 0xFF);
f010089a:	3c ff                	cmp    $0xff,%al
f010089c:	0f 95 c0             	setne  %al
f010089f:	0f b6 f0             	movzbl %al,%esi
f01008a2:	89 35 2c f0 2c f0    	mov    %esi,0xf02cf02c
f01008a8:	89 da                	mov    %ebx,%edx
f01008aa:	ec                   	in     (%dx),%al
f01008ab:	89 ca                	mov    %ecx,%edx
f01008ad:	ec                   	in     (%dx),%al
	(void) inb(COM1+COM_IIR);
	(void) inb(COM1+COM_RX);

	// Enable serial interrupts
	if (serial_exists)
f01008ae:	85 f6                	test   %esi,%esi
f01008b0:	74 1d                	je     f01008cf <cons_init+0x112>
		irq_setmask_8259A(irq_mask_8259A & ~(1<<4));
f01008b2:	0f b7 05 b8 e3 11 f0 	movzwl 0xf011e3b8,%eax
f01008b9:	25 ef ff 00 00       	and    $0xffef,%eax
f01008be:	89 04 24             	mov    %eax,(%esp)
f01008c1:	e8 e9 2f 00 00       	call   f01038af <irq_setmask_8259A>
{
	cga_init();
	kbd_init();
	serial_init();

	if (!serial_exists)
f01008c6:	83 3d 2c f0 2c f0 00 	cmpl   $0x0,0xf02cf02c
f01008cd:	75 0c                	jne    f01008db <cons_init+0x11e>
		cprintf("Serial port does not exist!\n");
f01008cf:	c7 04 24 dc 6b 10 f0 	movl   $0xf0106bdc,(%esp)
f01008d6:	e8 04 31 00 00       	call   f01039df <cprintf>
}
f01008db:	83 c4 1c             	add    $0x1c,%esp
f01008de:	5b                   	pop    %ebx
f01008df:	5e                   	pop    %esi
f01008e0:	5f                   	pop    %edi
f01008e1:	5d                   	pop    %ebp
f01008e2:	c3                   	ret    
	...

f01008f0 <read_eip>:
// return EIP of caller.
// does not work if inlined.
// putting at the end of the file seems to prevent inlining.
unsigned
read_eip()
{
f01008f0:	55                   	push   %ebp
f01008f1:	89 e5                	mov    %esp,%ebp
	uint32_t callerpc;
	__asm __volatile("movl 4(%%ebp), %0" : "=r" (callerpc));
f01008f3:	8b 45 04             	mov    0x4(%ebp),%eax
	return callerpc;
}
f01008f6:	5d                   	pop    %ebp
f01008f7:	c3                   	ret    

f01008f8 <mon_kerninfo>:
	return 0;
}

int
mon_kerninfo(int argc, char **argv, struct Trapframe *tf)
{
f01008f8:	55                   	push   %ebp
f01008f9:	89 e5                	mov    %esp,%ebp
f01008fb:	83 ec 18             	sub    $0x18,%esp
	extern char _start[], etext[], edata[], end[];

	cprintf("Special kernel symbols:\n");
f01008fe:	c7 04 24 f9 6b 10 f0 	movl   $0xf0106bf9,(%esp)
f0100905:	e8 d5 30 00 00       	call   f01039df <cprintf>
	cprintf("  _start %08x (virt)  %08x (phys)\n", _start, _start - KERNBASE);
f010090a:	c7 44 24 08 0c 00 10 	movl   $0x10000c,0x8(%esp)
f0100911:	00 
f0100912:	c7 44 24 04 0c 00 10 	movl   $0xf010000c,0x4(%esp)
f0100919:	f0 
f010091a:	c7 04 24 b0 6d 10 f0 	movl   $0xf0106db0,(%esp)
f0100921:	e8 b9 30 00 00       	call   f01039df <cprintf>
	cprintf("  etext  %08x (virt)  %08x (phys)\n", etext, etext - KERNBASE);
f0100926:	c7 44 24 08 15 69 10 	movl   $0x106915,0x8(%esp)
f010092d:	00 
f010092e:	c7 44 24 04 15 69 10 	movl   $0xf0106915,0x4(%esp)
f0100935:	f0 
f0100936:	c7 04 24 d4 6d 10 f0 	movl   $0xf0106dd4,(%esp)
f010093d:	e8 9d 30 00 00       	call   f01039df <cprintf>
	cprintf("  edata  %08x (virt)  %08x (phys)\n", edata, edata - KERNBASE);
f0100942:	c7 44 24 08 44 ed 2c 	movl   $0x2ced44,0x8(%esp)
f0100949:	00 
f010094a:	c7 44 24 04 44 ed 2c 	movl   $0xf02ced44,0x4(%esp)
f0100951:	f0 
f0100952:	c7 04 24 f8 6d 10 f0 	movl   $0xf0106df8,(%esp)
f0100959:	e8 81 30 00 00       	call   f01039df <cprintf>
	cprintf("  end    %08x (virt)  %08x (phys)\n", end, end - KERNBASE);
f010095e:	c7 44 24 08 00 20 2d 	movl   $0x2d2000,0x8(%esp)
f0100965:	00 
f0100966:	c7 44 24 04 00 20 2d 	movl   $0xf02d2000,0x4(%esp)
f010096d:	f0 
f010096e:	c7 04 24 1c 6e 10 f0 	movl   $0xf0106e1c,(%esp)
f0100975:	e8 65 30 00 00       	call   f01039df <cprintf>
	cprintf("Kernel executable memory footprint: %dKB\n",
f010097a:	b8 ff 23 2d f0       	mov    $0xf02d23ff,%eax
f010097f:	2d 0c 00 10 f0       	sub    $0xf010000c,%eax
f0100984:	8d 90 ff 03 00 00    	lea    0x3ff(%eax),%edx
f010098a:	85 c0                	test   %eax,%eax
f010098c:	0f 48 c2             	cmovs  %edx,%eax
f010098f:	c1 f8 0a             	sar    $0xa,%eax
f0100992:	89 44 24 04          	mov    %eax,0x4(%esp)
f0100996:	c7 04 24 40 6e 10 f0 	movl   $0xf0106e40,(%esp)
f010099d:	e8 3d 30 00 00       	call   f01039df <cprintf>
		(end-_start+1023)/1024);
	return 0;
}
f01009a2:	b8 00 00 00 00       	mov    $0x0,%eax
f01009a7:	c9                   	leave  
f01009a8:	c3                   	ret    

f01009a9 <mon_help>:

/***** Implementations of basic kernel monitor commands *****/

int
mon_help(int argc, char **argv, struct Trapframe *tf)
{
f01009a9:	55                   	push   %ebp
f01009aa:	89 e5                	mov    %esp,%ebp
f01009ac:	57                   	push   %edi
f01009ad:	56                   	push   %esi
f01009ae:	53                   	push   %ebx
f01009af:	83 ec 1c             	sub    $0x1c,%esp
f01009b2:	bb 00 00 00 00       	mov    $0x0,%ebx
	int i;

	for (i = 0; i < NCOMMANDS; i++)
		cprintf("%s - %s\n", commands[i].name, commands[i].desc);
f01009b7:	be c4 6f 10 f0       	mov    $0xf0106fc4,%esi
f01009bc:	bf c0 6f 10 f0       	mov    $0xf0106fc0,%edi
f01009c1:	8b 04 33             	mov    (%ebx,%esi,1),%eax
f01009c4:	89 44 24 08          	mov    %eax,0x8(%esp)
f01009c8:	8b 04 3b             	mov    (%ebx,%edi,1),%eax
f01009cb:	89 44 24 04          	mov    %eax,0x4(%esp)
f01009cf:	c7 04 24 12 6c 10 f0 	movl   $0xf0106c12,(%esp)
f01009d6:	e8 04 30 00 00       	call   f01039df <cprintf>
f01009db:	83 c3 0c             	add    $0xc,%ebx
int
mon_help(int argc, char **argv, struct Trapframe *tf)
{
	int i;

	for (i = 0; i < NCOMMANDS; i++)
f01009de:	83 fb 60             	cmp    $0x60,%ebx
f01009e1:	75 de                	jne    f01009c1 <mon_help+0x18>
		cprintf("%s - %s\n", commands[i].name, commands[i].desc);
	return 0;
}
f01009e3:	b8 00 00 00 00       	mov    $0x0,%eax
f01009e8:	83 c4 1c             	add    $0x1c,%esp
f01009eb:	5b                   	pop    %ebx
f01009ec:	5e                   	pop    %esi
f01009ed:	5f                   	pop    %edi
f01009ee:	5d                   	pop    %ebp
f01009ef:	c3                   	ret    

f01009f0 <monitor>:
	return 0;
}

void
monitor(struct Trapframe *tf)
{
f01009f0:	55                   	push   %ebp
f01009f1:	89 e5                	mov    %esp,%ebp
f01009f3:	57                   	push   %edi
f01009f4:	56                   	push   %esi
f01009f5:	53                   	push   %ebx
f01009f6:	83 ec 5c             	sub    $0x5c,%esp
	char *buf;

	cprintf("Welcome to the JOS kernel monitor!\n");
f01009f9:	c7 04 24 6c 6e 10 f0 	movl   $0xf0106e6c,(%esp)
f0100a00:	e8 da 2f 00 00       	call   f01039df <cprintf>
	cprintf("Type 'help' for a list of commands.\n");
f0100a05:	c7 04 24 90 6e 10 f0 	movl   $0xf0106e90,(%esp)
f0100a0c:	e8 ce 2f 00 00       	call   f01039df <cprintf>

	if (tf != NULL)
f0100a11:	83 7d 08 00          	cmpl   $0x0,0x8(%ebp)
f0100a15:	74 0b                	je     f0100a22 <monitor+0x32>
		print_trapframe(tf);
f0100a17:	8b 45 08             	mov    0x8(%ebp),%eax
f0100a1a:	89 04 24             	mov    %eax,(%esp)
f0100a1d:	e8 f8 36 00 00       	call   f010411a <print_trapframe>

	while (1) {
		buf = readline("K> ");
f0100a22:	c7 04 24 1b 6c 10 f0 	movl   $0xf0106c1b,(%esp)
f0100a29:	e8 e2 4d 00 00       	call   f0105810 <readline>
f0100a2e:	89 c3                	mov    %eax,%ebx
		if (buf != NULL)
f0100a30:	85 c0                	test   %eax,%eax
f0100a32:	74 ee                	je     f0100a22 <monitor+0x32>
	char *argv[MAXARGS];
	int i;

	// Parse the command buffer into whitespace-separated arguments
	argc = 0;
	argv[argc] = 0;
f0100a34:	c7 45 a8 00 00 00 00 	movl   $0x0,-0x58(%ebp)
f0100a3b:	be 00 00 00 00       	mov    $0x0,%esi
f0100a40:	eb 06                	jmp    f0100a48 <monitor+0x58>
	while (1) {
		// gobble whitespace
		while (*buf && strchr(WHITESPACE, *buf))
			*buf++ = 0;
f0100a42:	c6 03 00             	movb   $0x0,(%ebx)
f0100a45:	83 c3 01             	add    $0x1,%ebx
	// Parse the command buffer into whitespace-separated arguments
	argc = 0;
	argv[argc] = 0;
	while (1) {
		// gobble whitespace
		while (*buf && strchr(WHITESPACE, *buf))
f0100a48:	0f b6 03             	movzbl (%ebx),%eax
f0100a4b:	84 c0                	test   %al,%al
f0100a4d:	74 6c                	je     f0100abb <monitor+0xcb>
f0100a4f:	0f be c0             	movsbl %al,%eax
f0100a52:	89 44 24 04          	mov    %eax,0x4(%esp)
f0100a56:	c7 04 24 1f 6c 10 f0 	movl   $0xf0106c1f,(%esp)
f0100a5d:	e8 ec 4f 00 00       	call   f0105a4e <strchr>
f0100a62:	85 c0                	test   %eax,%eax
f0100a64:	75 dc                	jne    f0100a42 <monitor+0x52>
			*buf++ = 0;
		if (*buf == 0)
f0100a66:	80 3b 00             	cmpb   $0x0,(%ebx)
f0100a69:	74 50                	je     f0100abb <monitor+0xcb>
			break;

		// save and scan past next arg
		if (argc == MAXARGS-1) {
f0100a6b:	83 fe 0f             	cmp    $0xf,%esi
f0100a6e:	66 90                	xchg   %ax,%ax
f0100a70:	75 16                	jne    f0100a88 <monitor+0x98>
			cprintf("Too many arguments (max %d)\n", MAXARGS);
f0100a72:	c7 44 24 04 10 00 00 	movl   $0x10,0x4(%esp)
f0100a79:	00 
f0100a7a:	c7 04 24 24 6c 10 f0 	movl   $0xf0106c24,(%esp)
f0100a81:	e8 59 2f 00 00       	call   f01039df <cprintf>
f0100a86:	eb 9a                	jmp    f0100a22 <monitor+0x32>
			return 0;
		}
		argv[argc++] = buf;
f0100a88:	89 5c b5 a8          	mov    %ebx,-0x58(%ebp,%esi,4)
f0100a8c:	83 c6 01             	add    $0x1,%esi
		while (*buf && !strchr(WHITESPACE, *buf))
f0100a8f:	0f b6 03             	movzbl (%ebx),%eax
f0100a92:	84 c0                	test   %al,%al
f0100a94:	75 0c                	jne    f0100aa2 <monitor+0xb2>
f0100a96:	eb b0                	jmp    f0100a48 <monitor+0x58>
			buf++;
f0100a98:	83 c3 01             	add    $0x1,%ebx
		if (argc == MAXARGS-1) {
			cprintf("Too many arguments (max %d)\n", MAXARGS);
			return 0;
		}
		argv[argc++] = buf;
		while (*buf && !strchr(WHITESPACE, *buf))
f0100a9b:	0f b6 03             	movzbl (%ebx),%eax
f0100a9e:	84 c0                	test   %al,%al
f0100aa0:	74 a6                	je     f0100a48 <monitor+0x58>
f0100aa2:	0f be c0             	movsbl %al,%eax
f0100aa5:	89 44 24 04          	mov    %eax,0x4(%esp)
f0100aa9:	c7 04 24 1f 6c 10 f0 	movl   $0xf0106c1f,(%esp)
f0100ab0:	e8 99 4f 00 00       	call   f0105a4e <strchr>
f0100ab5:	85 c0                	test   %eax,%eax
f0100ab7:	74 df                	je     f0100a98 <monitor+0xa8>
f0100ab9:	eb 8d                	jmp    f0100a48 <monitor+0x58>
			buf++;
	}
	argv[argc] = 0;
f0100abb:	c7 44 b5 a8 00 00 00 	movl   $0x0,-0x58(%ebp,%esi,4)
f0100ac2:	00 

	// Lookup and invoke the command
	if (argc == 0)
f0100ac3:	85 f6                	test   %esi,%esi
f0100ac5:	0f 84 57 ff ff ff    	je     f0100a22 <monitor+0x32>
f0100acb:	bb c0 6f 10 f0       	mov    $0xf0106fc0,%ebx
f0100ad0:	bf 00 00 00 00       	mov    $0x0,%edi
		return 0;
	for (i = 0; i < NCOMMANDS; i++) {
		if (strcmp(argv[0], commands[i].name) == 0)
f0100ad5:	8b 03                	mov    (%ebx),%eax
f0100ad7:	89 44 24 04          	mov    %eax,0x4(%esp)
f0100adb:	8b 45 a8             	mov    -0x58(%ebp),%eax
f0100ade:	89 04 24             	mov    %eax,(%esp)
f0100ae1:	e8 f3 4e 00 00       	call   f01059d9 <strcmp>
f0100ae6:	85 c0                	test   %eax,%eax
f0100ae8:	75 23                	jne    f0100b0d <monitor+0x11d>
			return commands[i].func(argc, argv, tf);
f0100aea:	6b ff 0c             	imul   $0xc,%edi,%edi
f0100aed:	8b 45 08             	mov    0x8(%ebp),%eax
f0100af0:	89 44 24 08          	mov    %eax,0x8(%esp)
f0100af4:	8d 45 a8             	lea    -0x58(%ebp),%eax
f0100af7:	89 44 24 04          	mov    %eax,0x4(%esp)
f0100afb:	89 34 24             	mov    %esi,(%esp)
f0100afe:	ff 97 c8 6f 10 f0    	call   *-0xfef9038(%edi)
		print_trapframe(tf);

	while (1) {
		buf = readline("K> ");
		if (buf != NULL)
			if (runcmd(buf, tf) < 0)
f0100b04:	85 c0                	test   %eax,%eax
f0100b06:	78 28                	js     f0100b30 <monitor+0x140>
f0100b08:	e9 15 ff ff ff       	jmp    f0100a22 <monitor+0x32>
	argv[argc] = 0;

	// Lookup and invoke the command
	if (argc == 0)
		return 0;
	for (i = 0; i < NCOMMANDS; i++) {
f0100b0d:	83 c7 01             	add    $0x1,%edi
f0100b10:	83 c3 0c             	add    $0xc,%ebx
f0100b13:	83 ff 08             	cmp    $0x8,%edi
f0100b16:	75 bd                	jne    f0100ad5 <monitor+0xe5>
		if (strcmp(argv[0], commands[i].name) == 0)
			return commands[i].func(argc, argv, tf);
	}
	cprintf("Unknown command '%s'\n", argv[0]);
f0100b18:	8b 45 a8             	mov    -0x58(%ebp),%eax
f0100b1b:	89 44 24 04          	mov    %eax,0x4(%esp)
f0100b1f:	c7 04 24 41 6c 10 f0 	movl   $0xf0106c41,(%esp)
f0100b26:	e8 b4 2e 00 00       	call   f01039df <cprintf>
f0100b2b:	e9 f2 fe ff ff       	jmp    f0100a22 <monitor+0x32>
		buf = readline("K> ");
		if (buf != NULL)
			if (runcmd(buf, tf) < 0)
				break;
	}
}
f0100b30:	83 c4 5c             	add    $0x5c,%esp
f0100b33:	5b                   	pop    %ebx
f0100b34:	5e                   	pop    %esi
f0100b35:	5f                   	pop    %edi
f0100b36:	5d                   	pop    %ebp
f0100b37:	c3                   	ret    

f0100b38 <mon_page_status>:
    return 0;
}
extern struct Page_list page_free_list;	

int
mon_page_status(int argc, char **argv, struct Trapframe *tf) {
f0100b38:	55                   	push   %ebp
f0100b39:	89 e5                	mov    %esp,%ebp
f0100b3b:	53                   	push   %ebx
f0100b3c:	83 ec 14             	sub    $0x14,%esp
    if (argc != 2) {
f0100b3f:	83 7d 08 02          	cmpl   $0x2,0x8(%ebp)
f0100b43:	74 16                	je     f0100b5b <mon_page_status+0x23>
        cprintf("\t Usage: page_status [Physical Address]\n");
f0100b45:	c7 04 24 b8 6e 10 f0 	movl   $0xf0106eb8,(%esp)
f0100b4c:	e8 8e 2e 00 00       	call   f01039df <cprintf>
f0100b51:	b8 ff ff ff ff       	mov    $0xffffffff,%eax
        return -1;
f0100b56:	e9 91 00 00 00       	jmp    f0100bec <mon_page_status+0xb4>
    }
    physaddr_t  addr    = strtol(argv [1], NULL, 16);
f0100b5b:	c7 44 24 08 10 00 00 	movl   $0x10,0x8(%esp)
f0100b62:	00 
f0100b63:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
f0100b6a:	00 
f0100b6b:	8b 45 0c             	mov    0xc(%ebp),%eax
f0100b6e:	8b 40 04             	mov    0x4(%eax),%eax
f0100b71:	89 04 24             	mov    %eax,(%esp)
f0100b74:	e8 a2 50 00 00       	call   f0105c1b <strtol>
    if (addr >=0 && addr < (npage << PGSHIFT)) {
f0100b79:	8b 15 20 ff 2c f0    	mov    0xf02cff20,%edx
f0100b7f:	c1 e2 0c             	shl    $0xc,%edx
f0100b82:	39 d0                	cmp    %edx,%eax
f0100b84:	73 55                	jae    f0100bdb <mon_page_status+0xa3>
        struct Page *page;
        int found   = 0;
        LIST_FOREACH(page, &page_free_list, pp_link) {
f0100b86:	8b 15 1c ff 2c f0    	mov    0xf02cff1c,%edx
f0100b8c:	85 d2                	test   %edx,%edx
f0100b8e:	74 62                	je     f0100bf2 <mon_page_status+0xba>
void user_mem_assert(struct Env *env, const void *va, size_t len, int perm);

static inline ppn_t
page2ppn(struct Page *pp)
{
	return pp - pages;
f0100b90:	8b 1d 2c ff 2c f0    	mov    0xf02cff2c,%ebx
            //cprintf("%x\n", page);
            if (addr == page2pa(page)) {
f0100b96:	89 d1                	mov    %edx,%ecx
f0100b98:	29 d9                	sub    %ebx,%ecx
f0100b9a:	c1 f9 02             	sar    $0x2,%ecx
f0100b9d:	69 c9 ab aa aa aa    	imul   $0xaaaaaaab,%ecx,%ecx
f0100ba3:	c1 e1 0c             	shl    $0xc,%ecx
f0100ba6:	39 c8                	cmp    %ecx,%eax
f0100ba8:	75 16                	jne    f0100bc0 <mon_page_status+0x88>
f0100baa:	eb 1c                	jmp    f0100bc8 <mon_page_status+0x90>
f0100bac:	89 d1                	mov    %edx,%ecx
f0100bae:	29 d9                	sub    %ebx,%ecx
f0100bb0:	c1 f9 02             	sar    $0x2,%ecx
f0100bb3:	69 c9 ab aa aa aa    	imul   $0xaaaaaaab,%ecx,%ecx
f0100bb9:	c1 e1 0c             	shl    $0xc,%ecx
f0100bbc:	39 c8                	cmp    %ecx,%eax
f0100bbe:	74 08                	je     f0100bc8 <mon_page_status+0x90>
    }
    physaddr_t  addr    = strtol(argv [1], NULL, 16);
    if (addr >=0 && addr < (npage << PGSHIFT)) {
        struct Page *page;
        int found   = 0;
        LIST_FOREACH(page, &page_free_list, pp_link) {
f0100bc0:	8b 12                	mov    (%edx),%edx
f0100bc2:	85 d2                	test   %edx,%edx
f0100bc4:	75 e6                	jne    f0100bac <mon_page_status+0x74>
f0100bc6:	eb 2a                	jmp    f0100bf2 <mon_page_status+0xba>
            }
        }
        if (found == 0)
            cprintf("\tallocated\n");
        else
            cprintf("\tfree\n");
f0100bc8:	c7 04 24 57 6c 10 f0 	movl   $0xf0106c57,(%esp)
f0100bcf:	e8 0b 2e 00 00       	call   f01039df <cprintf>
f0100bd4:	b8 00 00 00 00       	mov    $0x0,%eax
f0100bd9:	eb 11                	jmp    f0100bec <mon_page_status+0xb4>
    } else {
        cprintf("\t invalid address\n");
f0100bdb:	c7 04 24 5e 6c 10 f0 	movl   $0xf0106c5e,(%esp)
f0100be2:	e8 f8 2d 00 00       	call   f01039df <cprintf>
f0100be7:	b8 00 00 00 00       	mov    $0x0,%eax
    }
    return 0;
}
f0100bec:	83 c4 14             	add    $0x14,%esp
f0100bef:	5b                   	pop    %ebx
f0100bf0:	5d                   	pop    %ebp
f0100bf1:	c3                   	ret    
                found   = 1;
                break;
            }
        }
        if (found == 0)
            cprintf("\tallocated\n");
f0100bf2:	c7 04 24 71 6c 10 f0 	movl   $0xf0106c71,(%esp)
f0100bf9:	e8 e1 2d 00 00       	call   f01039df <cprintf>
f0100bfe:	b8 00 00 00 00       	mov    $0x0,%eax
f0100c03:	eb e7                	jmp    f0100bec <mon_page_status+0xb4>

f0100c05 <mon_free_page>:
    curenv->env_tf.tf_eflags    = curenv->env_tf.tf_eflags | FL_TF;
    env_run(curenv);
}

int
mon_free_page(int argc, char **argv, struct Trapframe *tf) {
f0100c05:	55                   	push   %ebp
f0100c06:	89 e5                	mov    %esp,%ebp
f0100c08:	83 ec 18             	sub    $0x18,%esp
    if (argc != 2) {
f0100c0b:	83 7d 08 02          	cmpl   $0x2,0x8(%ebp)
f0100c0f:	74 13                	je     f0100c24 <mon_free_page+0x1f>
        cprintf("\t Usage: free_page [Physical Address]\n");
f0100c11:	c7 04 24 e4 6e 10 f0 	movl   $0xf0106ee4,(%esp)
f0100c18:	e8 c2 2d 00 00       	call   f01039df <cprintf>
f0100c1d:	b8 ff ff ff ff       	mov    $0xffffffff,%eax
        return -1;
f0100c22:	eb 7c                	jmp    f0100ca0 <mon_free_page+0x9b>
    }
    physaddr_t  addr    = strtol(argv [1], NULL, 16);
f0100c24:	c7 44 24 08 10 00 00 	movl   $0x10,0x8(%esp)
f0100c2b:	00 
f0100c2c:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
f0100c33:	00 
f0100c34:	8b 45 0c             	mov    0xc(%ebp),%eax
f0100c37:	8b 40 04             	mov    0x4(%eax),%eax
f0100c3a:	89 04 24             	mov    %eax,(%esp)
f0100c3d:	e8 d9 4f 00 00       	call   f0105c1b <strtol>
    if (addr >=0 && addr < (npage << PGSHIFT)) {
f0100c42:	8b 15 20 ff 2c f0    	mov    0xf02cff20,%edx
f0100c48:	89 d1                	mov    %edx,%ecx
f0100c4a:	c1 e1 0c             	shl    $0xc,%ecx
f0100c4d:	39 c8                	cmp    %ecx,%eax
f0100c4f:	73 3e                	jae    f0100c8f <mon_free_page+0x8a>
}

static inline struct Page*
pa2page(physaddr_t pa)
{
	if (PPN(pa) >= npage)
f0100c51:	c1 e8 0c             	shr    $0xc,%eax
f0100c54:	39 c2                	cmp    %eax,%edx
f0100c56:	77 1c                	ja     f0100c74 <mon_free_page+0x6f>
		panic("pa2page called with invalid pa");
f0100c58:	c7 44 24 08 0c 6f 10 	movl   $0xf0106f0c,0x8(%esp)
f0100c5f:	f0 
f0100c60:	c7 44 24 04 53 00 00 	movl   $0x53,0x4(%esp)
f0100c67:	00 
f0100c68:	c7 04 24 7d 6c 10 f0 	movl   $0xf0106c7d,(%esp)
f0100c6f:	e8 11 f4 ff ff       	call   f0100085 <_panic>
        page_free(pa2page(PTE_ADDR(addr)));
f0100c74:	8d 04 40             	lea    (%eax,%eax,2),%eax
f0100c77:	c1 e0 02             	shl    $0x2,%eax
f0100c7a:	03 05 2c ff 2c f0    	add    0xf02cff2c,%eax
f0100c80:	89 04 24             	mov    %eax,(%esp)
f0100c83:	e8 f7 02 00 00       	call   f0100f7f <page_free>
f0100c88:	b8 00 00 00 00       	mov    $0x0,%eax
f0100c8d:	eb 11                	jmp    f0100ca0 <mon_free_page+0x9b>
    } else {
        cprintf("\t invalid address\n");
f0100c8f:	c7 04 24 5e 6c 10 f0 	movl   $0xf0106c5e,(%esp)
f0100c96:	e8 44 2d 00 00       	call   f01039df <cprintf>
f0100c9b:	b8 00 00 00 00       	mov    $0x0,%eax
    }
    return 0;
}
f0100ca0:	c9                   	leave  
f0100ca1:	c3                   	ret    

f0100ca2 <mon_single_step>:
    curenv->env_tf.tf_eflags    = curenv->env_tf.tf_eflags & (~FL_TF);
    env_run(curenv);
}

int
mon_single_step(int argc, char **argv, struct Trapframe *tf) {
f0100ca2:	55                   	push   %ebp
f0100ca3:	89 e5                	mov    %esp,%ebp
f0100ca5:	83 ec 18             	sub    $0x18,%esp
    assert(curenv && curenv->env_status == ENV_RUNNABLE);
f0100ca8:	a1 60 f2 2c f0       	mov    0xf02cf260,%eax
f0100cad:	85 c0                	test   %eax,%eax
f0100caf:	74 06                	je     f0100cb7 <mon_single_step+0x15>
f0100cb1:	83 78 54 01          	cmpl   $0x1,0x54(%eax)
f0100cb5:	74 24                	je     f0100cdb <mon_single_step+0x39>
f0100cb7:	c7 44 24 0c 2c 6f 10 	movl   $0xf0106f2c,0xc(%esp)
f0100cbe:	f0 
f0100cbf:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0100cc6:	f0 
f0100cc7:	c7 44 24 04 97 00 00 	movl   $0x97,0x4(%esp)
f0100cce:	00 
f0100ccf:	c7 04 24 a0 6c 10 f0 	movl   $0xf0106ca0,(%esp)
f0100cd6:	e8 aa f3 ff ff       	call   f0100085 <_panic>
    curenv->env_tf.tf_eflags    = curenv->env_tf.tf_eflags | FL_TF;
f0100cdb:	81 48 38 00 01 00 00 	orl    $0x100,0x38(%eax)
    env_run(curenv);
f0100ce2:	a1 60 f2 2c f0       	mov    0xf02cf260,%eax
f0100ce7:	89 04 24             	mov    %eax,(%esp)
f0100cea:	e8 30 24 00 00       	call   f010311f <env_run>

f0100cef <mon_continue>:
    }
    return 0;
}

int
mon_continue(int argc, char **argv, struct Trapframe *tf) {
f0100cef:	55                   	push   %ebp
f0100cf0:	89 e5                	mov    %esp,%ebp
f0100cf2:	83 ec 18             	sub    $0x18,%esp
    assert(curenv && curenv->env_status == ENV_RUNNABLE);
f0100cf5:	a1 60 f2 2c f0       	mov    0xf02cf260,%eax
f0100cfa:	85 c0                	test   %eax,%eax
f0100cfc:	74 06                	je     f0100d04 <mon_continue+0x15>
f0100cfe:	83 78 54 01          	cmpl   $0x1,0x54(%eax)
f0100d02:	74 24                	je     f0100d28 <mon_continue+0x39>
f0100d04:	c7 44 24 0c 2c 6f 10 	movl   $0xf0106f2c,0xc(%esp)
f0100d0b:	f0 
f0100d0c:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0100d13:	f0 
f0100d14:	c7 44 24 04 90 00 00 	movl   $0x90,0x4(%esp)
f0100d1b:	00 
f0100d1c:	c7 04 24 a0 6c 10 f0 	movl   $0xf0106ca0,(%esp)
f0100d23:	e8 5d f3 ff ff       	call   f0100085 <_panic>
    curenv->env_tf.tf_eflags    = curenv->env_tf.tf_eflags & (~FL_TF);
f0100d28:	81 60 38 ff fe ff ff 	andl   $0xfffffeff,0x38(%eax)
    env_run(curenv);
f0100d2f:	a1 60 f2 2c f0       	mov    0xf02cf260,%eax
f0100d34:	89 04 24             	mov    %eax,(%esp)
f0100d37:	e8 e3 23 00 00       	call   f010311f <env_run>

f0100d3c <mon_alloc_page>:

	return 0;
}

int
mon_alloc_page(int argc, char **argv, struct Trapframe *tf) {
f0100d3c:	55                   	push   %ebp
f0100d3d:	89 e5                	mov    %esp,%ebp
f0100d3f:	83 ec 28             	sub    $0x28,%esp
    struct Page *page;
    if (!page_alloc(&page)) {
f0100d42:	8d 45 f4             	lea    -0xc(%ebp),%eax
f0100d45:	89 04 24             	mov    %eax,(%esp)
f0100d48:	e8 7e 03 00 00       	call   f01010cb <page_alloc>
f0100d4d:	85 c0                	test   %eax,%eax
f0100d4f:	75 25                	jne    f0100d76 <mon_alloc_page+0x3a>
        cprintf("\t0x%x\n", page2pa(page));
f0100d51:	8b 45 f4             	mov    -0xc(%ebp),%eax
f0100d54:	2b 05 2c ff 2c f0    	sub    0xf02cff2c,%eax
f0100d5a:	c1 f8 02             	sar    $0x2,%eax
f0100d5d:	69 c0 ab aa aa aa    	imul   $0xaaaaaaab,%eax,%eax
f0100d63:	c1 e0 0c             	shl    $0xc,%eax
f0100d66:	89 44 24 04          	mov    %eax,0x4(%esp)
f0100d6a:	c7 04 24 af 6c 10 f0 	movl   $0xf0106caf,(%esp)
f0100d71:	e8 69 2c 00 00       	call   f01039df <cprintf>
    }
    return 0;
}
f0100d76:	b8 00 00 00 00       	mov    $0x0,%eax
f0100d7b:	c9                   	leave  
f0100d7c:	c3                   	ret    

f0100d7d <mon_backtrace>:
	return 0;
}

int
mon_backtrace(int argc, char **argv, struct Trapframe *tf)
{
f0100d7d:	55                   	push   %ebp
f0100d7e:	89 e5                	mov    %esp,%ebp
f0100d80:	57                   	push   %edi
f0100d81:	56                   	push   %esi
f0100d82:	53                   	push   %ebx
f0100d83:	83 ec 4c             	sub    $0x4c,%esp
	uint32_t ebp	= 0;
	uint32_t eip	= 0;
	uint32_t i;
    
    if (tf == NULL) {
f0100d86:	83 7d 10 00          	cmpl   $0x0,0x10(%ebp)
f0100d8a:	75 04                	jne    f0100d90 <mon_backtrace+0x13>

static __inline uint32_t
read_ebp(void)
{
        uint32_t ebp;
        __asm __volatile("movl %%ebp,%0" : "=r" (ebp));
f0100d8c:	89 eb                	mov    %ebp,%ebx
f0100d8e:	eb 1d                	jmp    f0100dad <mon_backtrace+0x30>
        ebp	= read_ebp();
    } else {
        ebp = tf->tf_regs.reg_ebp;
f0100d90:	8b 45 10             	mov    0x10(%ebp),%eax
f0100d93:	8b 58 08             	mov    0x8(%eax),%ebx
	    if ((tf->tf_cs & 3) == 3)
f0100d96:	0f b7 40 34          	movzwl 0x34(%eax),%eax
f0100d9a:	83 e0 03             	and    $0x3,%eax
f0100d9d:	83 f8 03             	cmp    $0x3,%eax
f0100da0:	75 0b                	jne    f0100dad <mon_backtrace+0x30>
}

static __inline void
lcr3(uint32_t val)
{
	__asm __volatile("movl %0,%%cr3" : : "r" (val));
f0100da2:	a1 60 f2 2c f0       	mov    0xf02cf260,%eax
f0100da7:	8b 40 60             	mov    0x60(%eax),%eax
f0100daa:	0f 22 d8             	mov    %eax,%cr3
            lcr3(curenv->env_cr3);
    }
    cprintf("Trapframe: %x\n", tf);
f0100dad:	8b 55 10             	mov    0x10(%ebp),%edx
f0100db0:	89 54 24 04          	mov    %edx,0x4(%esp)
f0100db4:	c7 04 24 b6 6c 10 f0 	movl   $0xf0106cb6,(%esp)
f0100dbb:	e8 1f 2c 00 00       	call   f01039df <cprintf>
	cprintf("Stack backtrace:\n");
f0100dc0:	c7 04 24 c5 6c 10 f0 	movl   $0xf0106cc5,(%esp)
f0100dc7:	e8 13 2c 00 00       	call   f01039df <cprintf>
	while (ebp != 0) {
f0100dcc:	85 db                	test   %ebx,%ebx
f0100dce:	0f 84 ae 00 00 00    	je     f0100e82 <mon_backtrace+0x105>
		eip	= *((uint32_t *)(ebp+0x4));
f0100dd4:	8b 7b 04             	mov    0x4(%ebx),%edi
		//Print stack trace.
		cprintf("\tebp %08x eip %08x args %08x %08x %08x %08x %08x\n", ebp, *((uint32_t *)(ebp+0x4)), *((uint32_t *)(ebp + 0x8)), *((uint32_t *)(ebp + 0xc)), *((uint32_t *)(ebp + 0x10)), *((uint32_t *)(ebp + 0x14)), *((uint32_t *)(ebp + 0x18)));
f0100dd7:	8b 43 18             	mov    0x18(%ebx),%eax
f0100dda:	89 44 24 1c          	mov    %eax,0x1c(%esp)
f0100dde:	8b 43 14             	mov    0x14(%ebx),%eax
f0100de1:	89 44 24 18          	mov    %eax,0x18(%esp)
f0100de5:	8b 43 10             	mov    0x10(%ebx),%eax
f0100de8:	89 44 24 14          	mov    %eax,0x14(%esp)
f0100dec:	8b 43 0c             	mov    0xc(%ebx),%eax
f0100def:	89 44 24 10          	mov    %eax,0x10(%esp)
f0100df3:	8b 43 08             	mov    0x8(%ebx),%eax
f0100df6:	89 44 24 0c          	mov    %eax,0xc(%esp)
f0100dfa:	89 7c 24 08          	mov    %edi,0x8(%esp)
f0100dfe:	89 5c 24 04          	mov    %ebx,0x4(%esp)
f0100e02:	c7 04 24 5c 6f 10 f0 	movl   $0xf0106f5c,(%esp)
f0100e09:	e8 d1 2b 00 00       	call   f01039df <cprintf>
		//Print File info
		struct Eipdebuginfo info;
		if (debuginfo_eip((uintptr_t)(eip), &info)==0) {
f0100e0e:	8d 45 d0             	lea    -0x30(%ebp),%eax
f0100e11:	89 44 24 04          	mov    %eax,0x4(%esp)
f0100e15:	89 3c 24             	mov    %edi,(%esp)
f0100e18:	e8 f1 40 00 00       	call   f0104f0e <debuginfo_eip>
f0100e1d:	85 c0                	test   %eax,%eax
f0100e1f:	75 57                	jne    f0100e78 <mon_backtrace+0xfb>
			cprintf("\t\t%s:%d: ",info.eip_file, info.eip_line);
f0100e21:	8b 45 d4             	mov    -0x2c(%ebp),%eax
f0100e24:	89 44 24 08          	mov    %eax,0x8(%esp)
f0100e28:	8b 45 d0             	mov    -0x30(%ebp),%eax
f0100e2b:	89 44 24 04          	mov    %eax,0x4(%esp)
f0100e2f:	c7 04 24 d7 6c 10 f0 	movl   $0xf0106cd7,(%esp)
f0100e36:	e8 a4 2b 00 00       	call   f01039df <cprintf>
			for (i = 0; i < info.eip_fn_namelen; i++) {
f0100e3b:	83 7d dc 00          	cmpl   $0x0,-0x24(%ebp)
f0100e3f:	74 24                	je     f0100e65 <mon_backtrace+0xe8>
f0100e41:	be 00 00 00 00       	mov    $0x0,%esi
				cprintf("%c", info.eip_fn_name[i]);
f0100e46:	8b 45 d8             	mov    -0x28(%ebp),%eax
f0100e49:	0f be 04 30          	movsbl (%eax,%esi,1),%eax
f0100e4d:	89 44 24 04          	mov    %eax,0x4(%esp)
f0100e51:	c7 04 24 e1 6c 10 f0 	movl   $0xf0106ce1,(%esp)
f0100e58:	e8 82 2b 00 00       	call   f01039df <cprintf>
		cprintf("\tebp %08x eip %08x args %08x %08x %08x %08x %08x\n", ebp, *((uint32_t *)(ebp+0x4)), *((uint32_t *)(ebp + 0x8)), *((uint32_t *)(ebp + 0xc)), *((uint32_t *)(ebp + 0x10)), *((uint32_t *)(ebp + 0x14)), *((uint32_t *)(ebp + 0x18)));
		//Print File info
		struct Eipdebuginfo info;
		if (debuginfo_eip((uintptr_t)(eip), &info)==0) {
			cprintf("\t\t%s:%d: ",info.eip_file, info.eip_line);
			for (i = 0; i < info.eip_fn_namelen; i++) {
f0100e5d:	83 c6 01             	add    $0x1,%esi
f0100e60:	39 75 dc             	cmp    %esi,-0x24(%ebp)
f0100e63:	77 e1                	ja     f0100e46 <mon_backtrace+0xc9>
				cprintf("%c", info.eip_fn_name[i]);
			}
			cprintf("+%d\n", eip-info.eip_fn_addr);
f0100e65:	2b 7d e0             	sub    -0x20(%ebp),%edi
f0100e68:	89 7c 24 04          	mov    %edi,0x4(%esp)
f0100e6c:	c7 04 24 e4 6c 10 f0 	movl   $0xf0106ce4,(%esp)
f0100e73:	e8 67 2b 00 00       	call   f01039df <cprintf>
		}
		ebp	= *((uint32_t *)ebp);
f0100e78:	8b 1b                	mov    (%ebx),%ebx
	    if ((tf->tf_cs & 3) == 3)
            lcr3(curenv->env_cr3);
    }
    cprintf("Trapframe: %x\n", tf);
	cprintf("Stack backtrace:\n");
	while (ebp != 0) {
f0100e7a:	85 db                	test   %ebx,%ebx
f0100e7c:	0f 85 52 ff ff ff    	jne    f0100dd4 <mon_backtrace+0x57>
			}
			cprintf("+%d\n", eip-info.eip_fn_addr);
		}
		ebp	= *((uint32_t *)ebp);
	}
    if (tf != NULL && ((tf->tf_cs & 3) == 3))
f0100e82:	83 7d 10 00          	cmpl   $0x0,0x10(%ebp)
f0100e86:	74 17                	je     f0100e9f <mon_backtrace+0x122>
f0100e88:	8b 55 10             	mov    0x10(%ebp),%edx
f0100e8b:	0f b7 42 34          	movzwl 0x34(%edx),%eax
f0100e8f:	83 e0 03             	and    $0x3,%eax
f0100e92:	83 f8 03             	cmp    $0x3,%eax
f0100e95:	75 08                	jne    f0100e9f <mon_backtrace+0x122>
f0100e97:	a1 24 ff 2c f0       	mov    0xf02cff24,%eax
f0100e9c:	0f 22 d8             	mov    %eax,%cr3
        lcr3(boot_cr3);

	return 0;
}
f0100e9f:	b8 00 00 00 00       	mov    $0x0,%eax
f0100ea4:	83 c4 4c             	add    $0x4c,%esp
f0100ea7:	5b                   	pop    %ebx
f0100ea8:	5e                   	pop    %esi
f0100ea9:	5f                   	pop    %edi
f0100eaa:	5d                   	pop    %ebp
f0100eab:	c3                   	ret    
f0100eac:	00 00                	add    %al,(%eax)
	...

f0100eb0 <page_init>:
// allocator functions below to allocate and deallocate physical
// memory via the page_free_list.
//
void
page_init(void)
{
f0100eb0:	55                   	push   %ebp
f0100eb1:	89 e5                	mov    %esp,%ebp
f0100eb3:	56                   	push   %esi
f0100eb4:	53                   	push   %ebx
	//     in physical memory?  Which pages are already in use for
	//     page tables and other data structures?
	//
	// Change the code to reflect this.
	int i;
  char *freemem   = ROUNDUP(boot_freemem, PGSIZE);
f0100eb5:	8b 35 54 f2 2c f0    	mov    0xf02cf254,%esi
f0100ebb:	81 c6 ff 0f 00 00    	add    $0xfff,%esi
f0100ec1:	81 e6 00 f0 ff ff    	and    $0xfffff000,%esi
  pages [0].pp_ref    = 1;
f0100ec7:	a1 2c ff 2c f0       	mov    0xf02cff2c,%eax
f0100ecc:	66 c7 40 08 01 00    	movw   $0x1,0x8(%eax)
	LIST_INIT(&page_free_list);
f0100ed2:	c7 05 1c ff 2c f0 00 	movl   $0x0,0xf02cff1c
f0100ed9:	00 00 00 
	for (i = 1; i < npage; i++) {
f0100edc:	83 3d 20 ff 2c f0 01 	cmpl   $0x1,0xf02cff20
f0100ee3:	0f 86 92 00 00 00    	jbe    f0100f7b <page_init+0xcb>
f0100ee9:	ba 01 00 00 00       	mov    $0x1,%edx
f0100eee:	b8 01 00 00 00       	mov    $0x1,%eax
    uint32_t va = KERNBASE + i*PGSIZE;
f0100ef3:	8d 8a 00 00 0f 00    	lea    0xf0000(%edx),%ecx
f0100ef9:	c1 e1 0c             	shl    $0xc,%ecx

    if ((va >= KERNBASE && va < (KERNBASE + IOPHYSMEM)) ||
f0100efc:	8d 99 00 00 00 10    	lea    0x10000000(%ecx),%ebx
f0100f02:	81 fb ff ff 09 00    	cmp    $0x9ffff,%ebx
f0100f08:	76 04                	jbe    f0100f0e <page_init+0x5e>
f0100f0a:	39 ce                	cmp    %ecx,%esi
f0100f0c:	77 4c                	ja     f0100f5a <page_init+0xaa>
      (va >= (KERNBASE + EXTPHYSMEM) && va < 0xF0100000) || 
      (va >= (uint32_t)freemem)) {
      pages[i].pp_ref = 0;
f0100f0e:	8d 14 52             	lea    (%edx,%edx,2),%edx
f0100f11:	c1 e2 02             	shl    $0x2,%edx
f0100f14:	8b 0d 2c ff 2c f0    	mov    0xf02cff2c,%ecx
f0100f1a:	66 c7 44 11 08 00 00 	movw   $0x0,0x8(%ecx,%edx,1)
      LIST_INSERT_HEAD(&page_free_list, &pages[i], pp_link);
f0100f21:	8b 0d 1c ff 2c f0    	mov    0xf02cff1c,%ecx
f0100f27:	8b 1d 2c ff 2c f0    	mov    0xf02cff2c,%ebx
f0100f2d:	89 0c 13             	mov    %ecx,(%ebx,%edx,1)
f0100f30:	85 c9                	test   %ecx,%ecx
f0100f32:	74 11                	je     f0100f45 <page_init+0x95>
f0100f34:	89 d3                	mov    %edx,%ebx
f0100f36:	03 1d 2c ff 2c f0    	add    0xf02cff2c,%ebx
f0100f3c:	8b 0d 1c ff 2c f0    	mov    0xf02cff1c,%ecx
f0100f42:	89 59 04             	mov    %ebx,0x4(%ecx)
f0100f45:	03 15 2c ff 2c f0    	add    0xf02cff2c,%edx
f0100f4b:	89 15 1c ff 2c f0    	mov    %edx,0xf02cff1c
f0100f51:	c7 42 04 1c ff 2c f0 	movl   $0xf02cff1c,0x4(%edx)
f0100f58:	eb 10                	jmp    f0100f6a <page_init+0xba>
    } else {
      pages[i].pp_ref = 1;
f0100f5a:	8d 0c 52             	lea    (%edx,%edx,2),%ecx
f0100f5d:	8b 15 2c ff 2c f0    	mov    0xf02cff2c,%edx
f0100f63:	66 c7 44 8a 08 01 00 	movw   $0x1,0x8(%edx,%ecx,4)
	// Change the code to reflect this.
	int i;
  char *freemem   = ROUNDUP(boot_freemem, PGSIZE);
  pages [0].pp_ref    = 1;
	LIST_INIT(&page_free_list);
	for (i = 1; i < npage; i++) {
f0100f6a:	83 c0 01             	add    $0x1,%eax
f0100f6d:	89 c2                	mov    %eax,%edx
f0100f6f:	39 05 20 ff 2c f0    	cmp    %eax,0xf02cff20
f0100f75:	0f 87 78 ff ff ff    	ja     f0100ef3 <page_init+0x43>
      LIST_INSERT_HEAD(&page_free_list, &pages[i], pp_link);
    } else {
      pages[i].pp_ref = 1;
    }
	}
}
f0100f7b:	5b                   	pop    %ebx
f0100f7c:	5e                   	pop    %esi
f0100f7d:	5d                   	pop    %ebp
f0100f7e:	c3                   	ret    

f0100f7f <page_free>:
// Return a page to the free list.
// (This function should only be called when pp->pp_ref reaches 0.)
//
void
page_free(struct Page *pp)
{
f0100f7f:	55                   	push   %ebp
f0100f80:	89 e5                	mov    %esp,%ebp
f0100f82:	8b 45 08             	mov    0x8(%ebp),%eax
  LIST_INSERT_HEAD(&page_free_list, pp, pp_link);
f0100f85:	8b 15 1c ff 2c f0    	mov    0xf02cff1c,%edx
f0100f8b:	89 10                	mov    %edx,(%eax)
f0100f8d:	85 d2                	test   %edx,%edx
f0100f8f:	74 09                	je     f0100f9a <page_free+0x1b>
f0100f91:	8b 15 1c ff 2c f0    	mov    0xf02cff1c,%edx
f0100f97:	89 42 04             	mov    %eax,0x4(%edx)
f0100f9a:	a3 1c ff 2c f0       	mov    %eax,0xf02cff1c
f0100f9f:	c7 40 04 1c ff 2c f0 	movl   $0xf02cff1c,0x4(%eax)
}
f0100fa6:	5d                   	pop    %ebp
f0100fa7:	c3                   	ret    

f0100fa8 <page_decref>:
// Decrement the reference count on a page,
// freeing it if there are no more refs.
//
void
page_decref(struct Page* pp)
{
f0100fa8:	55                   	push   %ebp
f0100fa9:	89 e5                	mov    %esp,%ebp
f0100fab:	83 ec 04             	sub    $0x4,%esp
f0100fae:	8b 45 08             	mov    0x8(%ebp),%eax
	if (--pp->pp_ref == 0)
f0100fb1:	0f b7 50 08          	movzwl 0x8(%eax),%edx
f0100fb5:	83 ea 01             	sub    $0x1,%edx
f0100fb8:	66 89 50 08          	mov    %dx,0x8(%eax)
f0100fbc:	66 85 d2             	test   %dx,%dx
f0100fbf:	75 08                	jne    f0100fc9 <page_decref+0x21>
		page_free(pp);
f0100fc1:	89 04 24             	mov    %eax,(%esp)
f0100fc4:	e8 b6 ff ff ff       	call   f0100f7f <page_free>
}
f0100fc9:	c9                   	leave  
f0100fca:	c3                   	ret    

f0100fcb <tlb_invalidate>:
// Invalidate a TLB entry, but only if the page tables being
// edited are the ones currently in use by the processor.
//
void
tlb_invalidate(pde_t *pgdir, void *va)
{
f0100fcb:	55                   	push   %ebp
f0100fcc:	89 e5                	mov    %esp,%ebp
	// Flush the entry only if we're modifying the current address space.
	if (!curenv || curenv->env_pgdir == pgdir)
f0100fce:	a1 60 f2 2c f0       	mov    0xf02cf260,%eax
f0100fd3:	85 c0                	test   %eax,%eax
f0100fd5:	74 08                	je     f0100fdf <tlb_invalidate+0x14>
f0100fd7:	8b 55 08             	mov    0x8(%ebp),%edx
f0100fda:	39 50 5c             	cmp    %edx,0x5c(%eax)
f0100fdd:	75 06                	jne    f0100fe5 <tlb_invalidate+0x1a>
}

static __inline void 
invlpg(void *addr)
{ 
	__asm __volatile("invlpg (%0)" : : "r" (addr) : "memory");
f0100fdf:	8b 45 0c             	mov    0xc(%ebp),%eax
f0100fe2:	0f 01 38             	invlpg (%eax)
		invlpg(va);
}
f0100fe5:	5d                   	pop    %ebp
f0100fe6:	c3                   	ret    

f0100fe7 <boot_alloc>:
// This function may ONLY be used during initialization,
// before the page_free_list has been set up.
// 
static void*
boot_alloc(uint32_t n, uint32_t align)
{
f0100fe7:	55                   	push   %ebp
f0100fe8:	89 e5                	mov    %esp,%ebp
f0100fea:	83 ec 28             	sub    $0x28,%esp
f0100fed:	89 5d f4             	mov    %ebx,-0xc(%ebp)
f0100ff0:	89 75 f8             	mov    %esi,-0x8(%ebp)
f0100ff3:	89 7d fc             	mov    %edi,-0x4(%ebp)
f0100ff6:	89 c3                	mov    %eax,%ebx
f0100ff8:	89 d7                	mov    %edx,%edi
	// 'end' is a magic symbol automatically generated by the linker,
	// which points to the end of the kernel's bss segment -
	// i.e., the first virtual address that the linker
	// did _not_ assign to any kernel code or global variables.
	if (boot_freemem == 0)
		boot_freemem = end;
f0100ffa:	83 3d 54 f2 2c f0 00 	cmpl   $0x0,0xf02cf254
    //Round off the memory.
    boot_freemem    = ROUNDUP(boot_freemem, align);
f0101001:	b8 00 20 2d f0       	mov    $0xf02d2000,%eax
f0101006:	0f 45 05 54 f2 2c f0 	cmovne 0xf02cf254,%eax
f010100d:	8d 4c 02 ff          	lea    -0x1(%edx,%eax,1),%ecx
f0101011:	89 c8                	mov    %ecx,%eax
f0101013:	ba 00 00 00 00       	mov    $0x0,%edx
f0101018:	f7 f7                	div    %edi
f010101a:	89 c8                	mov    %ecx,%eax
f010101c:	29 d0                	sub    %edx,%eax
f010101e:	a3 54 f2 2c f0       	mov    %eax,0xf02cf254

    //Assign the allocation to a pointer.
    if (((uint32_t)boot_freemem + n) >= (KERNBASE + maxpa)) {
f0101023:	8d 1c 18             	lea    (%eax,%ebx,1),%ebx
f0101026:	8b 15 48 f2 2c f0    	mov    0xf02cf248,%edx
f010102c:	81 ea 00 00 00 10    	sub    $0x10000000,%edx
f0101032:	39 d3                	cmp    %edx,%ebx
f0101034:	72 1c                	jb     f0101052 <boot_alloc+0x6b>
        panic("Allocation Failed. Stop harassing the machine.\n");
f0101036:	c7 44 24 08 20 70 10 	movl   $0xf0107020,0x8(%esp)
f010103d:	f0 
f010103e:	c7 44 24 04 7d 00 00 	movl   $0x7d,0x4(%esp)
f0101045:	00 
f0101046:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f010104d:	e8 33 f0 ff ff       	call   f0100085 <_panic>
    }
    v               = boot_freemem;
    boot_freemem    = (char *)((uint32_t)v + n);
f0101052:	89 1d 54 f2 2c f0    	mov    %ebx,0xf02cf254
	//	Step 2: save current value of boot_freemem as allocated chunk
	//	Step 3: increase boot_freemem to record allocation
	//	Step 4: return allocated chunk

	return v;
}
f0101058:	8b 5d f4             	mov    -0xc(%ebp),%ebx
f010105b:	8b 75 f8             	mov    -0x8(%ebp),%esi
f010105e:	8b 7d fc             	mov    -0x4(%ebp),%edi
f0101061:	89 ec                	mov    %ebp,%esp
f0101063:	5d                   	pop    %ebp
f0101064:	c3                   	ret    

f0101065 <check_va2pa>:
// this functionality for us!  We define our own version to help check
// the check_boot_pgdir() function; it shouldn't be used elsewhere.

static physaddr_t
check_va2pa(pde_t *pgdir, uintptr_t va)
{
f0101065:	55                   	push   %ebp
f0101066:	89 e5                	mov    %esp,%ebp
f0101068:	83 ec 18             	sub    $0x18,%esp
	pte_t *p;

	pgdir = &pgdir[PDX(va)];
	if (!(*pgdir & PTE_P))
f010106b:	89 d1                	mov    %edx,%ecx
f010106d:	c1 e9 16             	shr    $0x16,%ecx
f0101070:	8b 04 88             	mov    (%eax,%ecx,4),%eax
f0101073:	a8 01                	test   $0x1,%al
f0101075:	74 4d                	je     f01010c4 <check_va2pa+0x5f>
		return ~0;
	p = (pte_t*) KADDR(PTE_ADDR(*pgdir));
f0101077:	25 00 f0 ff ff       	and    $0xfffff000,%eax
f010107c:	89 c1                	mov    %eax,%ecx
f010107e:	c1 e9 0c             	shr    $0xc,%ecx
f0101081:	3b 0d 20 ff 2c f0    	cmp    0xf02cff20,%ecx
f0101087:	72 20                	jb     f01010a9 <check_va2pa+0x44>
f0101089:	89 44 24 0c          	mov    %eax,0xc(%esp)
f010108d:	c7 44 24 08 50 70 10 	movl   $0xf0107050,0x8(%esp)
f0101094:	f0 
f0101095:	c7 44 24 04 c8 01 00 	movl   $0x1c8,0x4(%esp)
f010109c:	00 
f010109d:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f01010a4:	e8 dc ef ff ff       	call   f0100085 <_panic>
	if (!(p[PTX(va)] & PTE_P))
f01010a9:	c1 ea 0c             	shr    $0xc,%edx
f01010ac:	81 e2 ff 03 00 00    	and    $0x3ff,%edx
f01010b2:	8b 84 90 00 00 00 f0 	mov    -0x10000000(%eax,%edx,4),%eax
f01010b9:	a8 01                	test   $0x1,%al
f01010bb:	74 07                	je     f01010c4 <check_va2pa+0x5f>
		return ~0;
	return PTE_ADDR(p[PTX(va)]);
f01010bd:	25 00 f0 ff ff       	and    $0xfffff000,%eax
f01010c2:	eb 05                	jmp    f01010c9 <check_va2pa+0x64>
f01010c4:	b8 ff ff ff ff       	mov    $0xffffffff,%eax
}
f01010c9:	c9                   	leave  
f01010ca:	c3                   	ret    

f01010cb <page_alloc>:
//   -E_NO_MEM -- otherwise 
//
// Hint: use LIST_FIRST, LIST_REMOVE, and page_initpp
int
page_alloc(struct Page **pp_store)
{
f01010cb:	55                   	push   %ebp
f01010cc:	89 e5                	mov    %esp,%ebp
f01010ce:	53                   	push   %ebx
f01010cf:	83 ec 14             	sub    $0x14,%esp
  struct Page *page   = NULL;
  
  if (LIST_EMPTY(&page_free_list)) {
f01010d2:	8b 1d 1c ff 2c f0    	mov    0xf02cff1c,%ebx
f01010d8:	b8 fc ff ff ff       	mov    $0xfffffffc,%eax
f01010dd:	85 db                	test   %ebx,%ebx
f01010df:	74 35                	je     f0101116 <page_alloc+0x4b>
    return -E_NO_MEM;
  } else {
    page        = LIST_FIRST(&page_free_list);
    LIST_REMOVE(page, pp_link); 
f01010e1:	8b 03                	mov    (%ebx),%eax
f01010e3:	85 c0                	test   %eax,%eax
f01010e5:	74 06                	je     f01010ed <page_alloc+0x22>
f01010e7:	8b 53 04             	mov    0x4(%ebx),%edx
f01010ea:	89 50 04             	mov    %edx,0x4(%eax)
f01010ed:	8b 43 04             	mov    0x4(%ebx),%eax
f01010f0:	8b 13                	mov    (%ebx),%edx
f01010f2:	89 10                	mov    %edx,(%eax)
// Note that the corresponding physical page is NOT initialized!
//
static void
page_initpp(struct Page *pp)
{
	memset(pp, 0, sizeof(*pp));
f01010f4:	c7 44 24 08 0c 00 00 	movl   $0xc,0x8(%esp)
f01010fb:	00 
f01010fc:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
f0101103:	00 
f0101104:	89 1c 24             	mov    %ebx,(%esp)
f0101107:	e8 9a 49 00 00       	call   f0105aa6 <memset>
    return -E_NO_MEM;
  } else {
    page        = LIST_FIRST(&page_free_list);
    LIST_REMOVE(page, pp_link); 
    page_initpp(page);
    *pp_store   = page;
f010110c:	8b 45 08             	mov    0x8(%ebp),%eax
f010110f:	89 18                	mov    %ebx,(%eax)
f0101111:	b8 00 00 00 00       	mov    $0x0,%eax
    return 0;
  }
}
f0101116:	83 c4 14             	add    $0x14,%esp
f0101119:	5b                   	pop    %ebx
f010111a:	5d                   	pop    %ebp
f010111b:	c3                   	ret    

f010111c <pgdir_walk>:
// Hint 2: the x86 MMU checks permission bits in both the page directory
// and the page table, so it's safe to leave permissions in the page
// more permissive than strictly necessary.
pte_t *
pgdir_walk(pde_t *pgdir, const void *va, int create)
{
f010111c:	55                   	push   %ebp
f010111d:	89 e5                	mov    %esp,%ebp
f010111f:	56                   	push   %esi
f0101120:	53                   	push   %ebx
f0101121:	83 ec 20             	sub    $0x20,%esp
f0101124:	8b 45 08             	mov    0x8(%ebp),%eax
  if (pgdir) {
f0101127:	85 c0                	test   %eax,%eax
f0101129:	0f 84 4e 01 00 00    	je     f010127d <pgdir_walk+0x161>
    pte_t *pte  = (pte_t *)pgdir [PDX(va)];
f010112f:	8b 75 0c             	mov    0xc(%ebp),%esi
f0101132:	89 f2                	mov    %esi,%edx
f0101134:	c1 ea 16             	shr    $0x16,%edx
f0101137:	8d 1c 90             	lea    (%eax,%edx,4),%ebx
f010113a:	8b 03                	mov    (%ebx),%eax
f010113c:	89 c2                	mov    %eax,%edx
    if (pte == NULL || (!((physaddr_t)pte & PTE_P) && create)) {
f010113e:	85 c0                	test   %eax,%eax
f0101140:	74 13                	je     f0101155 <pgdir_walk+0x39>
f0101142:	83 e2 01             	and    $0x1,%edx
f0101145:	0f 85 ea 00 00 00    	jne    f0101235 <pgdir_walk+0x119>
f010114b:	83 7d 10 00          	cmpl   $0x0,0x10(%ebp)
f010114f:	0f 84 e0 00 00 00    	je     f0101235 <pgdir_walk+0x119>
      struct Page *page   = NULL;
f0101155:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
      if (page_alloc(&page) == 0) {
f010115c:	8d 45 f4             	lea    -0xc(%ebp),%eax
f010115f:	89 04 24             	mov    %eax,(%esp)
f0101162:	e8 64 ff ff ff       	call   f01010cb <page_alloc>
f0101167:	85 c0                	test   %eax,%eax
f0101169:	0f 85 0e 01 00 00    	jne    f010127d <pgdir_walk+0x161>
        page->pp_ref    += 1;
f010116f:	8b 45 f4             	mov    -0xc(%ebp),%eax
f0101172:	66 83 40 08 01       	addw   $0x1,0x8(%eax)
        pgdir [PDX(va)] = page2pa(page)|PTE_P;
f0101177:	8b 45 f4             	mov    -0xc(%ebp),%eax
f010117a:	89 c2                	mov    %eax,%edx
f010117c:	2b 15 2c ff 2c f0    	sub    0xf02cff2c,%edx
f0101182:	c1 fa 02             	sar    $0x2,%edx
f0101185:	69 d2 ab aa aa aa    	imul   $0xaaaaaaab,%edx,%edx
f010118b:	c1 e2 0c             	shl    $0xc,%edx
f010118e:	83 ca 01             	or     $0x1,%edx
f0101191:	89 13                	mov    %edx,(%ebx)
}

static inline physaddr_t
page2pa(struct Page *pp)
{
	return page2ppn(pp) << PGSHIFT;
f0101193:	2b 05 2c ff 2c f0    	sub    0xf02cff2c,%eax
f0101199:	c1 f8 02             	sar    $0x2,%eax
f010119c:	69 c0 ab aa aa aa    	imul   $0xaaaaaaab,%eax,%eax
f01011a2:	c1 e0 0c             	shl    $0xc,%eax
}

static inline void*
page2kva(struct Page *pp)
{
	return KADDR(page2pa(pp));
f01011a5:	89 c2                	mov    %eax,%edx
f01011a7:	c1 ea 0c             	shr    $0xc,%edx
f01011aa:	3b 15 20 ff 2c f0    	cmp    0xf02cff20,%edx
f01011b0:	72 20                	jb     f01011d2 <pgdir_walk+0xb6>
f01011b2:	89 44 24 0c          	mov    %eax,0xc(%esp)
f01011b6:	c7 44 24 08 50 70 10 	movl   $0xf0107050,0x8(%esp)
f01011bd:	f0 
f01011be:	c7 44 24 04 5a 00 00 	movl   $0x5a,0x4(%esp)
f01011c5:	00 
f01011c6:	c7 04 24 7d 6c 10 f0 	movl   $0xf0106c7d,(%esp)
f01011cd:	e8 b3 ee ff ff       	call   f0100085 <_panic>
        memset(page2kva(page), 0, PGSIZE);
f01011d2:	c7 44 24 08 00 10 00 	movl   $0x1000,0x8(%esp)
f01011d9:	00 
f01011da:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
f01011e1:	00 
f01011e2:	2d 00 00 00 10       	sub    $0x10000000,%eax
f01011e7:	89 04 24             	mov    %eax,(%esp)
f01011ea:	e8 b7 48 00 00       	call   f0105aa6 <memset>
        return KADDR((uintptr_t)((pte_t *)(PTE_ADDR(pgdir [PDX(va)])) + PTX(va)));
f01011ef:	8b 03                	mov    (%ebx),%eax
f01011f1:	25 00 f0 ff ff       	and    $0xfffff000,%eax
f01011f6:	c1 ee 0a             	shr    $0xa,%esi
f01011f9:	81 e6 fc 0f 00 00    	and    $0xffc,%esi
f01011ff:	01 f0                	add    %esi,%eax
f0101201:	89 c2                	mov    %eax,%edx
f0101203:	c1 ea 0c             	shr    $0xc,%edx
f0101206:	3b 15 20 ff 2c f0    	cmp    0xf02cff20,%edx
f010120c:	72 20                	jb     f010122e <pgdir_walk+0x112>
f010120e:	89 44 24 0c          	mov    %eax,0xc(%esp)
f0101212:	c7 44 24 08 50 70 10 	movl   $0xf0107050,0x8(%esp)
f0101219:	f0 
f010121a:	c7 44 24 04 58 02 00 	movl   $0x258,0x4(%esp)
f0101221:	00 
f0101222:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0101229:	e8 57 ee ff ff       	call   f0100085 <_panic>
f010122e:	2d 00 00 00 10       	sub    $0x10000000,%eax
f0101233:	eb 4d                	jmp    f0101282 <pgdir_walk+0x166>
      }
    } else if ((uint32_t)pte & PTE_P) {
f0101235:	85 d2                	test   %edx,%edx
f0101237:	74 44                	je     f010127d <pgdir_walk+0x161>
      return KADDR((uintptr_t)((pte_t *)PTE_ADDR(pte) + PTX(va)));
f0101239:	25 00 f0 ff ff       	and    $0xfffff000,%eax
f010123e:	c1 ee 0a             	shr    $0xa,%esi
f0101241:	81 e6 fc 0f 00 00    	and    $0xffc,%esi
f0101247:	01 f0                	add    %esi,%eax
f0101249:	89 c2                	mov    %eax,%edx
f010124b:	c1 ea 0c             	shr    $0xc,%edx
f010124e:	3b 15 20 ff 2c f0    	cmp    0xf02cff20,%edx
f0101254:	72 20                	jb     f0101276 <pgdir_walk+0x15a>
f0101256:	89 44 24 0c          	mov    %eax,0xc(%esp)
f010125a:	c7 44 24 08 50 70 10 	movl   $0xf0107050,0x8(%esp)
f0101261:	f0 
f0101262:	c7 44 24 04 5b 02 00 	movl   $0x25b,0x4(%esp)
f0101269:	00 
f010126a:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0101271:	e8 0f ee ff ff       	call   f0100085 <_panic>
f0101276:	2d 00 00 00 10       	sub    $0x10000000,%eax
f010127b:	eb 05                	jmp    f0101282 <pgdir_walk+0x166>
f010127d:	b8 00 00 00 00       	mov    $0x0,%eax
    }
  }
	return NULL;
}
f0101282:	83 c4 20             	add    $0x20,%esp
f0101285:	5b                   	pop    %ebx
f0101286:	5e                   	pop    %esi
f0101287:	5d                   	pop    %ebp
f0101288:	c3                   	ret    

f0101289 <page_lookup>:
//
// Hint: the TA solution uses pgdir_walk and pa2page.
//
struct Page *
page_lookup(pde_t *pgdir, void *va, pte_t **pte_store)
{
f0101289:	55                   	push   %ebp
f010128a:	89 e5                	mov    %esp,%ebp
f010128c:	53                   	push   %ebx
f010128d:	83 ec 14             	sub    $0x14,%esp
f0101290:	8b 45 08             	mov    0x8(%ebp),%eax
f0101293:	8b 5d 10             	mov    0x10(%ebp),%ebx
    if (pgdir != NULL) {
f0101296:	85 c0                	test   %eax,%eax
f0101298:	74 61                	je     f01012fb <page_lookup+0x72>
        pte_t *pte  = pgdir_walk(pgdir, va, 0);
f010129a:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
f01012a1:	00 
f01012a2:	8b 55 0c             	mov    0xc(%ebp),%edx
f01012a5:	89 54 24 04          	mov    %edx,0x4(%esp)
f01012a9:	89 04 24             	mov    %eax,(%esp)
f01012ac:	e8 6b fe ff ff       	call   f010111c <pgdir_walk>
        if (pte != NULL && (*pte & PTE_P)) {
f01012b1:	85 c0                	test   %eax,%eax
f01012b3:	74 46                	je     f01012fb <page_lookup+0x72>
f01012b5:	f6 00 01             	testb  $0x1,(%eax)
f01012b8:	74 41                	je     f01012fb <page_lookup+0x72>
            if (pte_store)
f01012ba:	85 db                	test   %ebx,%ebx
f01012bc:	8d 74 26 00          	lea    0x0(%esi,%eiz,1),%esi
f01012c0:	74 02                	je     f01012c4 <page_lookup+0x3b>
                *pte_store  = pte;
f01012c2:	89 03                	mov    %eax,(%ebx)
}

static inline struct Page*
pa2page(physaddr_t pa)
{
	if (PPN(pa) >= npage)
f01012c4:	8b 00                	mov    (%eax),%eax
f01012c6:	c1 e8 0c             	shr    $0xc,%eax
f01012c9:	3b 05 20 ff 2c f0    	cmp    0xf02cff20,%eax
f01012cf:	72 1c                	jb     f01012ed <page_lookup+0x64>
		panic("pa2page called with invalid pa");
f01012d1:	c7 44 24 08 0c 6f 10 	movl   $0xf0106f0c,0x8(%esp)
f01012d8:	f0 
f01012d9:	c7 44 24 04 53 00 00 	movl   $0x53,0x4(%esp)
f01012e0:	00 
f01012e1:	c7 04 24 7d 6c 10 f0 	movl   $0xf0106c7d,(%esp)
f01012e8:	e8 98 ed ff ff       	call   f0100085 <_panic>
	return &pages[PPN(pa)];
f01012ed:	8d 04 40             	lea    (%eax,%eax,2),%eax
f01012f0:	c1 e0 02             	shl    $0x2,%eax
f01012f3:	03 05 2c ff 2c f0    	add    0xf02cff2c,%eax
            return pa2page(PTE_ADDR(*pte));
f01012f9:	eb 05                	jmp    f0101300 <page_lookup+0x77>
f01012fb:	b8 00 00 00 00       	mov    $0x0,%eax
        }
    }
	return NULL;
}
f0101300:	83 c4 14             	add    $0x14,%esp
f0101303:	5b                   	pop    %ebx
f0101304:	5d                   	pop    %ebp
f0101305:	c3                   	ret    

f0101306 <user_mem_check>:
// Returns 0 if the user program can access this range of addresses,
// and -E_FAULT otherwise.
//
int
user_mem_check(struct Env *env, const void *va, size_t len, int perm)
{
f0101306:	55                   	push   %ebp
f0101307:	89 e5                	mov    %esp,%ebp
f0101309:	57                   	push   %edi
f010130a:	56                   	push   %esi
f010130b:	53                   	push   %ebx
f010130c:	83 ec 3c             	sub    $0x3c,%esp
f010130f:	8b 75 08             	mov    0x8(%ebp),%esi
  uint32_t i;
  uint32_t startAddr  = (uint32_t)ROUNDDOWN(va, PGSIZE);
f0101312:	8b 45 0c             	mov    0xc(%ebp),%eax
f0101315:	89 45 d0             	mov    %eax,-0x30(%ebp)
f0101318:	89 c3                	mov    %eax,%ebx
f010131a:	81 e3 00 f0 ff ff    	and    $0xfffff000,%ebx
  uint32_t endAddr    = (uint32_t)ROUNDDOWN(va+len, PGSIZE); 
f0101320:	03 45 10             	add    0x10(%ebp),%eax
f0101323:	25 00 f0 ff ff       	and    $0xfffff000,%eax
f0101328:	89 45 d4             	mov    %eax,-0x2c(%ebp)
  perm    |= PTE_P;
f010132b:	8b 7d 14             	mov    0x14(%ebp),%edi
f010132e:	83 cf 01             	or     $0x1,%edi

  if (startAddr < ULIM && endAddr < ULIM) {
f0101331:	81 fb ff ff 7f ef    	cmp    $0xef7fffff,%ebx
f0101337:	0f 87 8e 00 00 00    	ja     f01013cb <user_mem_check+0xc5>
f010133d:	3d ff ff 7f ef       	cmp    $0xef7fffff,%eax
f0101342:	0f 87 83 00 00 00    	ja     f01013cb <user_mem_check+0xc5>
    for (i=startAddr; i <=endAddr; i+=PGSIZE) {
f0101348:	39 c3                	cmp    %eax,%ebx
f010134a:	0f 87 8a 00 00 00    	ja     f01013da <user_mem_check+0xd4>
      pte_t *pte  = NULL;
f0101350:	c7 45 e4 00 00 00 00 	movl   $0x0,-0x1c(%ebp)
      if (!page_lookup(env->env_pgdir, (void *)i, &pte)) {
f0101357:	8d 45 e4             	lea    -0x1c(%ebp),%eax
f010135a:	89 44 24 08          	mov    %eax,0x8(%esp)
f010135e:	89 5c 24 04          	mov    %ebx,0x4(%esp)
f0101362:	8b 46 5c             	mov    0x5c(%esi),%eax
f0101365:	89 04 24             	mov    %eax,(%esp)
f0101368:	e8 1c ff ff ff       	call   f0101289 <page_lookup>
f010136d:	85 c0                	test   %eax,%eax
f010136f:	75 21                	jne    f0101392 <user_mem_check+0x8c>
        if ((uint32_t)va > i)
f0101371:	39 5d d0             	cmp    %ebx,-0x30(%ebp)
f0101374:	76 0f                	jbe    f0101385 <user_mem_check+0x7f>
          user_mem_check_addr = (uint32_t)va;
f0101376:	8b 45 d0             	mov    -0x30(%ebp),%eax
f0101379:	a3 58 f2 2c f0       	mov    %eax,0xf02cf258
f010137e:	b8 fa ff ff ff       	mov    $0xfffffffa,%eax
f0101383:	eb 5a                	jmp    f01013df <user_mem_check+0xd9>
        else
          user_mem_check_addr = (uint32_t)i;
f0101385:	89 1d 58 f2 2c f0    	mov    %ebx,0xf02cf258
f010138b:	b8 fa ff ff ff       	mov    $0xfffffffa,%eax
f0101390:	eb 4d                	jmp    f01013df <user_mem_check+0xd9>
        return -E_FAULT;
      } else if ((*pte & perm)!=perm) {
f0101392:	8b 45 e4             	mov    -0x1c(%ebp),%eax
f0101395:	8b 00                	mov    (%eax),%eax
f0101397:	21 f8                	and    %edi,%eax
f0101399:	39 c7                	cmp    %eax,%edi
f010139b:	74 21                	je     f01013be <user_mem_check+0xb8>
        if ((uint32_t)va > i)
f010139d:	39 5d d0             	cmp    %ebx,-0x30(%ebp)
f01013a0:	76 0f                	jbe    f01013b1 <user_mem_check+0xab>
          user_mem_check_addr = (uint32_t)va;
f01013a2:	8b 45 d0             	mov    -0x30(%ebp),%eax
f01013a5:	a3 58 f2 2c f0       	mov    %eax,0xf02cf258
f01013aa:	b8 fa ff ff ff       	mov    $0xfffffffa,%eax
f01013af:	eb 2e                	jmp    f01013df <user_mem_check+0xd9>
        else
          user_mem_check_addr = (uint32_t)i;
f01013b1:	89 1d 58 f2 2c f0    	mov    %ebx,0xf02cf258
f01013b7:	b8 fa ff ff ff       	mov    $0xfffffffa,%eax
f01013bc:	eb 21                	jmp    f01013df <user_mem_check+0xd9>
  uint32_t startAddr  = (uint32_t)ROUNDDOWN(va, PGSIZE);
  uint32_t endAddr    = (uint32_t)ROUNDDOWN(va+len, PGSIZE); 
  perm    |= PTE_P;

  if (startAddr < ULIM && endAddr < ULIM) {
    for (i=startAddr; i <=endAddr; i+=PGSIZE) {
f01013be:	81 c3 00 10 00 00    	add    $0x1000,%ebx
f01013c4:	39 5d d4             	cmp    %ebx,-0x2c(%ebp)
f01013c7:	73 87                	jae    f0101350 <user_mem_check+0x4a>
f01013c9:	eb 0f                	jmp    f01013da <user_mem_check+0xd4>
          user_mem_check_addr = (uint32_t)i;
        return -E_FAULT;
      }
    }
  } else {
    user_mem_check_addr = (uint32_t)va;
f01013cb:	8b 45 d0             	mov    -0x30(%ebp),%eax
f01013ce:	a3 58 f2 2c f0       	mov    %eax,0xf02cf258
f01013d3:	b8 fa ff ff ff       	mov    $0xfffffffa,%eax
    return -E_FAULT;
f01013d8:	eb 05                	jmp    f01013df <user_mem_check+0xd9>
f01013da:	b8 00 00 00 00       	mov    $0x0,%eax
  }
	return 0;
}
f01013df:	83 c4 3c             	add    $0x3c,%esp
f01013e2:	5b                   	pop    %ebx
f01013e3:	5e                   	pop    %esi
f01013e4:	5f                   	pop    %edi
f01013e5:	5d                   	pop    %ebp
f01013e6:	c3                   	ret    

f01013e7 <user_mem_assert>:
// If it cannot, 'env' is destroyed and, if env is the current
// environment, this function will not return.
//
void
user_mem_assert(struct Env *env, const void *va, size_t len, int perm)
{
f01013e7:	55                   	push   %ebp
f01013e8:	89 e5                	mov    %esp,%ebp
f01013ea:	53                   	push   %ebx
f01013eb:	83 ec 14             	sub    $0x14,%esp
f01013ee:	8b 5d 08             	mov    0x8(%ebp),%ebx
	if (user_mem_check(env, va, len, perm | PTE_U) < 0) {
f01013f1:	8b 45 14             	mov    0x14(%ebp),%eax
f01013f4:	83 c8 04             	or     $0x4,%eax
f01013f7:	89 44 24 0c          	mov    %eax,0xc(%esp)
f01013fb:	8b 45 10             	mov    0x10(%ebp),%eax
f01013fe:	89 44 24 08          	mov    %eax,0x8(%esp)
f0101402:	8b 45 0c             	mov    0xc(%ebp),%eax
f0101405:	89 44 24 04          	mov    %eax,0x4(%esp)
f0101409:	89 1c 24             	mov    %ebx,(%esp)
f010140c:	e8 f5 fe ff ff       	call   f0101306 <user_mem_check>
f0101411:	85 c0                	test   %eax,%eax
f0101413:	79 24                	jns    f0101439 <user_mem_assert+0x52>
		cprintf("[%08x] user_mem_check assertion failure for "
f0101415:	a1 58 f2 2c f0       	mov    0xf02cf258,%eax
f010141a:	89 44 24 08          	mov    %eax,0x8(%esp)
f010141e:	8b 43 4c             	mov    0x4c(%ebx),%eax
f0101421:	89 44 24 04          	mov    %eax,0x4(%esp)
f0101425:	c7 04 24 74 70 10 f0 	movl   $0xf0107074,(%esp)
f010142c:	e8 ae 25 00 00       	call   f01039df <cprintf>
			"va %08x\n", env->env_id, user_mem_check_addr);
		env_destroy(env);	// may not return
f0101431:	89 1c 24             	mov    %ebx,(%esp)
f0101434:	e8 f5 1e 00 00       	call   f010332e <env_destroy>
	}
}
f0101439:	83 c4 14             	add    $0x14,%esp
f010143c:	5b                   	pop    %ebx
f010143d:	5d                   	pop    %ebp
f010143e:	c3                   	ret    

f010143f <page_remove>:
// Hint: The TA solution is implemented using page_lookup,
// 	tlb_invalidate, and page_decref.
//
void
page_remove(pde_t *pgdir, void *va)
{
f010143f:	55                   	push   %ebp
f0101440:	89 e5                	mov    %esp,%ebp
f0101442:	83 ec 38             	sub    $0x38,%esp
f0101445:	89 5d f4             	mov    %ebx,-0xc(%ebp)
f0101448:	89 75 f8             	mov    %esi,-0x8(%ebp)
f010144b:	89 7d fc             	mov    %edi,-0x4(%ebp)
f010144e:	8b 7d 08             	mov    0x8(%ebp),%edi
f0101451:	8b 75 0c             	mov    0xc(%ebp),%esi
  pte_t *pte;
  struct Page *page   = page_lookup(pgdir, va, &pte);
f0101454:	8d 45 e4             	lea    -0x1c(%ebp),%eax
f0101457:	89 44 24 08          	mov    %eax,0x8(%esp)
f010145b:	89 74 24 04          	mov    %esi,0x4(%esp)
f010145f:	89 3c 24             	mov    %edi,(%esp)
f0101462:	e8 22 fe ff ff       	call   f0101289 <page_lookup>
f0101467:	89 c3                	mov    %eax,%ebx

  if (page != NULL) {
f0101469:	85 c0                	test   %eax,%eax
f010146b:	74 1d                	je     f010148a <page_remove+0x4b>
    tlb_invalidate(pgdir, va);
f010146d:	89 74 24 04          	mov    %esi,0x4(%esp)
f0101471:	89 3c 24             	mov    %edi,(%esp)
f0101474:	e8 52 fb ff ff       	call   f0100fcb <tlb_invalidate>
    page_decref(page);
f0101479:	89 1c 24             	mov    %ebx,(%esp)
f010147c:	e8 27 fb ff ff       	call   f0100fa8 <page_decref>
    *pte    = 0;
f0101481:	8b 45 e4             	mov    -0x1c(%ebp),%eax
f0101484:	c7 00 00 00 00 00    	movl   $0x0,(%eax)
  }
}
f010148a:	8b 5d f4             	mov    -0xc(%ebp),%ebx
f010148d:	8b 75 f8             	mov    -0x8(%ebp),%esi
f0101490:	8b 7d fc             	mov    -0x4(%ebp),%edi
f0101493:	89 ec                	mov    %ebp,%esp
f0101495:	5d                   	pop    %ebp
f0101496:	c3                   	ret    

f0101497 <page_insert>:
// Hint: The TA solution is implemented using pgdir_walk, page_remove,
// and page2pa.
//
int
page_insert(pde_t *pgdir, struct Page *pp, void *va, int perm) 
{
f0101497:	55                   	push   %ebp
f0101498:	89 e5                	mov    %esp,%ebp
f010149a:	83 ec 38             	sub    $0x38,%esp
f010149d:	89 5d f4             	mov    %ebx,-0xc(%ebp)
f01014a0:	89 75 f8             	mov    %esi,-0x8(%ebp)
f01014a3:	89 7d fc             	mov    %edi,-0x4(%ebp)
f01014a6:	8b 5d 08             	mov    0x8(%ebp),%ebx
f01014a9:	8b 7d 0c             	mov    0xc(%ebp),%edi
  if (pgdir && pp) {
f01014ac:	85 db                	test   %ebx,%ebx
f01014ae:	0f 84 c6 00 00 00    	je     f010157a <page_insert+0xe3>
f01014b4:	85 ff                	test   %edi,%edi
f01014b6:	0f 84 be 00 00 00    	je     f010157a <page_insert+0xe3>
    pte_t *pte  = pgdir_walk(pgdir, va, 1);
f01014bc:	c7 44 24 08 01 00 00 	movl   $0x1,0x8(%esp)
f01014c3:	00 
f01014c4:	8b 45 10             	mov    0x10(%ebp),%eax
f01014c7:	89 44 24 04          	mov    %eax,0x4(%esp)
f01014cb:	89 1c 24             	mov    %ebx,(%esp)
f01014ce:	e8 49 fc ff ff       	call   f010111c <pgdir_walk>
f01014d3:	89 c6                	mov    %eax,%esi
    if (pte != NULL) {
f01014d5:	85 c0                	test   %eax,%eax
f01014d7:	0f 84 9d 00 00 00    	je     f010157a <page_insert+0xe3>
      pgdir [PDX(va)] = pgdir [PDX(va)]|(perm&(~PTE_AVAIL));
f01014dd:	8b 45 10             	mov    0x10(%ebp),%eax
f01014e0:	c1 e8 16             	shr    $0x16,%eax
f01014e3:	8b 55 14             	mov    0x14(%ebp),%edx
f01014e6:	89 55 e4             	mov    %edx,-0x1c(%ebp)
f01014e9:	80 e6 f1             	and    $0xf1,%dh
f01014ec:	09 14 83             	or     %edx,(%ebx,%eax,4)
      if ((*pte & PTE_P) && (page2pa(pp) == PTE_ADDR(*pte))) {
f01014ef:	8b 16                	mov    (%esi),%edx
f01014f1:	f6 c2 01             	test   $0x1,%dl
f01014f4:	74 4d                	je     f0101543 <page_insert+0xac>
f01014f6:	81 e2 00 f0 ff ff    	and    $0xfffff000,%edx
f01014fc:	89 f8                	mov    %edi,%eax
f01014fe:	2b 05 2c ff 2c f0    	sub    0xf02cff2c,%eax
f0101504:	c1 f8 02             	sar    $0x2,%eax
f0101507:	69 c0 ab aa aa aa    	imul   $0xaaaaaaab,%eax,%eax
f010150d:	c1 e0 0c             	shl    $0xc,%eax
f0101510:	39 c2                	cmp    %eax,%edx
f0101512:	75 20                	jne    f0101534 <page_insert+0x9d>
        *pte    = PTE_ADDR(*pte)|perm|PTE_P;
f0101514:	8b 45 e4             	mov    -0x1c(%ebp),%eax
f0101517:	83 c8 01             	or     $0x1,%eax
f010151a:	09 c2                	or     %eax,%edx
f010151c:	89 16                	mov    %edx,(%esi)
        tlb_invalidate(pgdir, va);
f010151e:	8b 45 10             	mov    0x10(%ebp),%eax
f0101521:	89 44 24 04          	mov    %eax,0x4(%esp)
f0101525:	89 1c 24             	mov    %ebx,(%esp)
f0101528:	e8 9e fa ff ff       	call   f0100fcb <tlb_invalidate>
f010152d:	b8 00 00 00 00       	mov    $0x0,%eax
        return 0;
f0101532:	eb 4b                	jmp    f010157f <page_insert+0xe8>
      } else if (*pte & PTE_P) {
        page_remove(pgdir, va);
f0101534:	8b 55 10             	mov    0x10(%ebp),%edx
f0101537:	89 54 24 04          	mov    %edx,0x4(%esp)
f010153b:	89 1c 24             	mov    %ebx,(%esp)
f010153e:	e8 fc fe ff ff       	call   f010143f <page_remove>
      }
      pp->pp_ref  += 1;
f0101543:	66 83 47 08 01       	addw   $0x1,0x8(%edi)
      *pte    = page2pa(pp)|perm|PTE_P;
f0101548:	8b 55 e4             	mov    -0x1c(%ebp),%edx
f010154b:	83 ca 01             	or     $0x1,%edx
f010154e:	2b 3d 2c ff 2c f0    	sub    0xf02cff2c,%edi
f0101554:	c1 ff 02             	sar    $0x2,%edi
f0101557:	69 c7 ab aa aa aa    	imul   $0xaaaaaaab,%edi,%eax
f010155d:	c1 e0 0c             	shl    $0xc,%eax
f0101560:	09 d0                	or     %edx,%eax
f0101562:	89 06                	mov    %eax,(%esi)
      tlb_invalidate(pgdir, va);
f0101564:	8b 45 10             	mov    0x10(%ebp),%eax
f0101567:	89 44 24 04          	mov    %eax,0x4(%esp)
f010156b:	89 1c 24             	mov    %ebx,(%esp)
f010156e:	e8 58 fa ff ff       	call   f0100fcb <tlb_invalidate>
f0101573:	b8 00 00 00 00       	mov    $0x0,%eax
      return 0;
f0101578:	eb 05                	jmp    f010157f <page_insert+0xe8>
f010157a:	b8 fc ff ff ff       	mov    $0xfffffffc,%eax
    }
  }
	return -E_NO_MEM;
}
f010157f:	8b 5d f4             	mov    -0xc(%ebp),%ebx
f0101582:	8b 75 f8             	mov    -0x8(%ebp),%esi
f0101585:	8b 7d fc             	mov    -0x4(%ebp),%edi
f0101588:	89 ec                	mov    %ebp,%esp
f010158a:	5d                   	pop    %ebp
f010158b:	c3                   	ret    

f010158c <boot_map_segment>:
// mapped pages.
//
// Hint: the TA solution uses pgdir_walk
static void
boot_map_segment(pde_t *pgdir, uintptr_t la, size_t size, physaddr_t pa, int perm)
{
f010158c:	55                   	push   %ebp
f010158d:	89 e5                	mov    %esp,%ebp
f010158f:	57                   	push   %edi
f0101590:	56                   	push   %esi
f0101591:	53                   	push   %ebx
f0101592:	83 ec 2c             	sub    $0x2c,%esp
f0101595:	89 c6                	mov    %eax,%esi
f0101597:	89 55 d8             	mov    %edx,-0x28(%ebp)
f010159a:	89 4d dc             	mov    %ecx,-0x24(%ebp)
    int i,j;

    for (i = 0; i < size; i+=PGSIZE) {
f010159d:	85 c9                	test   %ecx,%ecx
f010159f:	0f 84 a8 00 00 00    	je     f010164d <boot_map_segment+0xc1>
f01015a5:	c7 45 e4 00 00 00 00 	movl   $0x0,-0x1c(%ebp)
f01015ac:	bf 00 00 00 00       	mov    $0x0,%edi
        pte_t *pte      = pgdir_walk(pgdir, (void *)(la + i), 1);
f01015b1:	8b 45 e4             	mov    -0x1c(%ebp),%eax
f01015b4:	03 45 d8             	add    -0x28(%ebp),%eax
f01015b7:	89 45 e0             	mov    %eax,-0x20(%ebp)
f01015ba:	c7 44 24 08 01 00 00 	movl   $0x1,0x8(%esp)
f01015c1:	00 
f01015c2:	89 44 24 04          	mov    %eax,0x4(%esp)
f01015c6:	89 34 24             	mov    %esi,(%esp)
f01015c9:	e8 4e fb ff ff       	call   f010111c <pgdir_walk>
f01015ce:	89 c3                	mov    %eax,%ebx
        physaddr_t addr = pa + i;
        if (pte != NULL) {
f01015d0:	85 c0                	test   %eax,%eax
f01015d2:	74 5b                	je     f010162f <boot_map_segment+0xa3>
{
    int i,j;

    for (i = 0; i < size; i+=PGSIZE) {
        pte_t *pte      = pgdir_walk(pgdir, (void *)(la + i), 1);
        physaddr_t addr = pa + i;
f01015d4:	8b 55 e4             	mov    -0x1c(%ebp),%edx
f01015d7:	03 55 08             	add    0x8(%ebp),%edx
f01015da:	89 55 e4             	mov    %edx,-0x1c(%ebp)
        if (pte != NULL) {
            if (*pte & PTE_P) {
f01015dd:	8b 00                	mov    (%eax),%eax
f01015df:	a8 01                	test   $0x1,%al
f01015e1:	74 44                	je     f0101627 <boot_map_segment+0x9b>
                if ((PTE_ADDR(*pte) != addr)) {
f01015e3:	25 00 f0 ff ff       	and    $0xfffff000,%eax
f01015e8:	39 d0                	cmp    %edx,%eax
f01015ea:	74 3b                	je     f0101627 <boot_map_segment+0x9b>
}

static inline struct Page*
pa2page(physaddr_t pa)
{
	if (PPN(pa) >= npage)
f01015ec:	c1 e8 0c             	shr    $0xc,%eax
f01015ef:	3b 05 20 ff 2c f0    	cmp    0xf02cff20,%eax
f01015f5:	72 1c                	jb     f0101613 <boot_map_segment+0x87>
		panic("pa2page called with invalid pa");
f01015f7:	c7 44 24 08 0c 6f 10 	movl   $0xf0106f0c,0x8(%esp)
f01015fe:	f0 
f01015ff:	c7 44 24 04 53 00 00 	movl   $0x53,0x4(%esp)
f0101606:	00 
f0101607:	c7 04 24 7d 6c 10 f0 	movl   $0xf0106c7d,(%esp)
f010160e:	e8 72 ea ff ff       	call   f0100085 <_panic>
                    page_decref(pa2page(PTE_ADDR(*pte)));
f0101613:	8d 04 40             	lea    (%eax,%eax,2),%eax
f0101616:	c1 e0 02             	shl    $0x2,%eax
f0101619:	03 05 2c ff 2c f0    	add    0xf02cff2c,%eax
f010161f:	89 04 24             	mov    %eax,(%esp)
f0101622:	e8 81 f9 ff ff       	call   f0100fa8 <page_decref>
                }
            }
            *pte    = addr|perm;
f0101627:	8b 45 e4             	mov    -0x1c(%ebp),%eax
f010162a:	0b 45 0c             	or     0xc(%ebp),%eax
f010162d:	89 03                	mov    %eax,(%ebx)
        }
        pgdir [PDX(la+i)]   = pgdir [PDX(la+i)]|perm;
f010162f:	8b 45 e0             	mov    -0x20(%ebp),%eax
f0101632:	c1 e8 16             	shr    $0x16,%eax
f0101635:	8b 55 0c             	mov    0xc(%ebp),%edx
f0101638:	09 14 86             	or     %edx,(%esi,%eax,4)
static void
boot_map_segment(pde_t *pgdir, uintptr_t la, size_t size, physaddr_t pa, int perm)
{
    int i,j;

    for (i = 0; i < size; i+=PGSIZE) {
f010163b:	81 c7 00 10 00 00    	add    $0x1000,%edi
f0101641:	89 7d e4             	mov    %edi,-0x1c(%ebp)
f0101644:	39 7d dc             	cmp    %edi,-0x24(%ebp)
f0101647:	0f 87 64 ff ff ff    	ja     f01015b1 <boot_map_segment+0x25>
            }
            *pte    = addr|perm;
        }
        pgdir [PDX(la+i)]   = pgdir [PDX(la+i)]|perm;
    }
}
f010164d:	83 c4 2c             	add    $0x2c,%esp
f0101650:	5b                   	pop    %ebx
f0101651:	5e                   	pop    %esi
f0101652:	5f                   	pop    %edi
f0101653:	5d                   	pop    %ebp
f0101654:	c3                   	ret    

f0101655 <nvram_read>:
	sizeof(gdt) - 1, (unsigned long) gdt
};

static int
nvram_read(int r)
{
f0101655:	55                   	push   %ebp
f0101656:	89 e5                	mov    %esp,%ebp
f0101658:	83 ec 18             	sub    $0x18,%esp
f010165b:	89 5d f8             	mov    %ebx,-0x8(%ebp)
f010165e:	89 75 fc             	mov    %esi,-0x4(%ebp)
f0101661:	89 c3                	mov    %eax,%ebx
	return mc146818_read(r) | (mc146818_read(r + 1) << 8);
f0101663:	89 04 24             	mov    %eax,(%esp)
f0101666:	e8 b9 21 00 00       	call   f0103824 <mc146818_read>
f010166b:	89 c6                	mov    %eax,%esi
f010166d:	83 c3 01             	add    $0x1,%ebx
f0101670:	89 1c 24             	mov    %ebx,(%esp)
f0101673:	e8 ac 21 00 00       	call   f0103824 <mc146818_read>
f0101678:	c1 e0 08             	shl    $0x8,%eax
f010167b:	09 f0                	or     %esi,%eax
}
f010167d:	8b 5d f8             	mov    -0x8(%ebp),%ebx
f0101680:	8b 75 fc             	mov    -0x4(%ebp),%esi
f0101683:	89 ec                	mov    %ebp,%esp
f0101685:	5d                   	pop    %ebp
f0101686:	c3                   	ret    

f0101687 <i386_detect_memory>:

void
i386_detect_memory(void)
{
f0101687:	55                   	push   %ebp
f0101688:	89 e5                	mov    %esp,%ebp
f010168a:	83 ec 18             	sub    $0x18,%esp
	// CMOS tells us how many kilobytes there are
	basemem = ROUNDDOWN(nvram_read(NVRAM_BASELO)*1024, PGSIZE);
f010168d:	b8 15 00 00 00       	mov    $0x15,%eax
f0101692:	e8 be ff ff ff       	call   f0101655 <nvram_read>
f0101697:	c1 e0 0a             	shl    $0xa,%eax
f010169a:	25 00 f0 ff ff       	and    $0xfffff000,%eax
f010169f:	a3 4c f2 2c f0       	mov    %eax,0xf02cf24c
	extmem = ROUNDDOWN(nvram_read(NVRAM_EXTLO)*1024, PGSIZE);
f01016a4:	b8 17 00 00 00       	mov    $0x17,%eax
f01016a9:	e8 a7 ff ff ff       	call   f0101655 <nvram_read>
f01016ae:	c1 e0 0a             	shl    $0xa,%eax
f01016b1:	25 00 f0 ff ff       	and    $0xfffff000,%eax
f01016b6:	a3 50 f2 2c f0       	mov    %eax,0xf02cf250

	// Calculate the maximum physical address based on whether
	// or not there is any extended memory.  See comment in <inc/mmu.h>.
	if (extmem)
f01016bb:	85 c0                	test   %eax,%eax
f01016bd:	74 0c                	je     f01016cb <i386_detect_memory+0x44>
		maxpa = EXTPHYSMEM + extmem;
f01016bf:	05 00 00 10 00       	add    $0x100000,%eax
f01016c4:	a3 48 f2 2c f0       	mov    %eax,0xf02cf248
f01016c9:	eb 0a                	jmp    f01016d5 <i386_detect_memory+0x4e>
	else
		maxpa = basemem;
f01016cb:	a1 4c f2 2c f0       	mov    0xf02cf24c,%eax
f01016d0:	a3 48 f2 2c f0       	mov    %eax,0xf02cf248


	npage = maxpa / PGSIZE;
f01016d5:	a1 48 f2 2c f0       	mov    0xf02cf248,%eax
f01016da:	89 c2                	mov    %eax,%edx
f01016dc:	c1 ea 0c             	shr    $0xc,%edx
f01016df:	89 15 20 ff 2c f0    	mov    %edx,0xf02cff20

	cprintf("Physical memory: %dK available, ", (int)(maxpa/1024));
f01016e5:	c1 e8 0a             	shr    $0xa,%eax
f01016e8:	89 44 24 04          	mov    %eax,0x4(%esp)
f01016ec:	c7 04 24 ac 70 10 f0 	movl   $0xf01070ac,(%esp)
f01016f3:	e8 e7 22 00 00       	call   f01039df <cprintf>
	cprintf("base = %dK, extended = %dK\n", (int)(basemem/1024), (int)(extmem/1024));
f01016f8:	a1 50 f2 2c f0       	mov    0xf02cf250,%eax
f01016fd:	c1 e8 0a             	shr    $0xa,%eax
f0101700:	89 44 24 08          	mov    %eax,0x8(%esp)
f0101704:	a1 4c f2 2c f0       	mov    0xf02cf24c,%eax
f0101709:	c1 e8 0a             	shr    $0xa,%eax
f010170c:	89 44 24 04          	mov    %eax,0x4(%esp)
f0101710:	c7 04 24 57 76 10 f0 	movl   $0xf0107657,(%esp)
f0101717:	e8 c3 22 00 00       	call   f01039df <cprintf>
}
f010171c:	c9                   	leave  
f010171d:	c3                   	ret    

f010171e <i386_vm_init>:
// From UTOP to ULIM, the user is allowed to read but not write.
// Above ULIM the user cannot read (or write). 

void
i386_vm_init(void)
{
f010171e:	55                   	push   %ebp
f010171f:	89 e5                	mov    %esp,%ebp
f0101721:	57                   	push   %edi
f0101722:	56                   	push   %esi
f0101723:	53                   	push   %ebx
f0101724:	83 ec 4c             	sub    $0x4c,%esp
    struct Env *env;

	//panic("i386_vm_init: This function is not finished\n");
	//////////////////////////////////////////////////////////////////////
	// create initial page directory.
	pgdir = boot_alloc(PGSIZE, PGSIZE);
f0101727:	ba 00 10 00 00       	mov    $0x1000,%edx
f010172c:	b8 00 10 00 00       	mov    $0x1000,%eax
f0101731:	e8 b1 f8 ff ff       	call   f0100fe7 <boot_alloc>
f0101736:	89 45 bc             	mov    %eax,-0x44(%ebp)
	memset(pgdir, 0, PGSIZE);
f0101739:	c7 44 24 08 00 10 00 	movl   $0x1000,0x8(%esp)
f0101740:	00 
f0101741:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
f0101748:	00 
f0101749:	89 04 24             	mov    %eax,(%esp)
f010174c:	e8 55 43 00 00       	call   f0105aa6 <memset>
	boot_pgdir = pgdir;
f0101751:	8b 45 bc             	mov    -0x44(%ebp),%eax
f0101754:	a3 28 ff 2c f0       	mov    %eax,0xf02cff28
	boot_cr3 = PADDR(pgdir);
f0101759:	3d ff ff ff ef       	cmp    $0xefffffff,%eax
f010175e:	77 20                	ja     f0101780 <i386_vm_init+0x62>
f0101760:	89 44 24 0c          	mov    %eax,0xc(%esp)
f0101764:	c7 44 24 08 d0 70 10 	movl   $0xf01070d0,0x8(%esp)
f010176b:	f0 
f010176c:	c7 44 24 04 aa 00 00 	movl   $0xaa,0x4(%esp)
f0101773:	00 
f0101774:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f010177b:	e8 05 e9 ff ff       	call   f0100085 <_panic>
f0101780:	05 00 00 00 10       	add    $0x10000000,%eax
f0101785:	a3 24 ff 2c f0       	mov    %eax,0xf02cff24
	// a virtual page table at virtual address VPT.
	// (For now, you don't have understand the greater purpose of the
	// following two lines.)

	// Permissions: kernel RW, user NONE
	pgdir[PDX(VPT)] = PADDR(pgdir)|PTE_W|PTE_P;
f010178a:	89 c2                	mov    %eax,%edx
f010178c:	83 ca 03             	or     $0x3,%edx
f010178f:	8b 4d bc             	mov    -0x44(%ebp),%ecx
f0101792:	89 91 fc 0e 00 00    	mov    %edx,0xefc(%ecx)

	// same for UVPT
	// Permissions: kernel R, user R 
	pgdir[PDX(UVPT)] = PADDR(pgdir)|PTE_U|PTE_P;
f0101798:	83 c8 05             	or     $0x5,%eax
f010179b:	89 81 f4 0e 00 00    	mov    %eax,0xef4(%ecx)
	// each physical page, there is a corresponding struct Page in this
	// array.  'npage' is the number of physical pages in memory.
	// User-level programs will get read-only access to the array as well.
	// Your code goes here:

  pages   = boot_alloc(sizeof(struct Page)*npage, PGSIZE); 
f01017a1:	a1 20 ff 2c f0       	mov    0xf02cff20,%eax
f01017a6:	8d 04 40             	lea    (%eax,%eax,2),%eax
f01017a9:	c1 e0 02             	shl    $0x2,%eax
f01017ac:	ba 00 10 00 00       	mov    $0x1000,%edx
f01017b1:	e8 31 f8 ff ff       	call   f0100fe7 <boot_alloc>
f01017b6:	a3 2c ff 2c f0       	mov    %eax,0xf02cff2c
	memset(pages, 0, sizeof(struct Page)*npage);
f01017bb:	8b 15 20 ff 2c f0    	mov    0xf02cff20,%edx
f01017c1:	8d 14 52             	lea    (%edx,%edx,2),%edx
f01017c4:	c1 e2 02             	shl    $0x2,%edx
f01017c7:	89 54 24 08          	mov    %edx,0x8(%esp)
f01017cb:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
f01017d2:	00 
f01017d3:	89 04 24             	mov    %eax,(%esp)
f01017d6:	e8 cb 42 00 00       	call   f0105aa6 <memset>
    
	//////////////////////////////////////////////////////////////////////
	// Make 'envs' point to an array of size 'NENV' of 'struct Env'.
	// LAB 3: Your code here.
  envs    = boot_alloc(sizeof(struct Env)*NENV, PGSIZE);
f01017db:	ba 00 10 00 00       	mov    $0x1000,%edx
f01017e0:	b8 00 f0 01 00       	mov    $0x1f000,%eax
f01017e5:	e8 fd f7 ff ff       	call   f0100fe7 <boot_alloc>
f01017ea:	a3 5c f2 2c f0       	mov    %eax,0xf02cf25c
  memset(envs, 0, sizeof(struct Env)*NENV);
f01017ef:	c7 44 24 08 00 f0 01 	movl   $0x1f000,0x8(%esp)
f01017f6:	00 
f01017f7:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
f01017fe:	00 
f01017ff:	89 04 24             	mov    %eax,(%esp)
f0101802:	e8 9f 42 00 00       	call   f0105aa6 <memset>
	//////////////////////////////////////////////////////////////////////
	// Now that we've allocated the initial kernel data structures, we set
	// up the list of free physical pages. Once we've done so, all further
	// memory management will go through the page_* functions. In
	// particular, we can now map memory using boot_map_segment or page_insert
	page_init();
f0101807:	e8 a4 f6 ff ff       	call   f0100eb0 <page_init>
	struct Page_list fl;

	// if there's a page that shouldn't be on
	// the free list, try to make sure it
	// eventually causes trouble.
	LIST_FOREACH(pp0, &page_free_list, pp_link) 
f010180c:	a1 1c ff 2c f0       	mov    0xf02cff1c,%eax
f0101811:	89 45 dc             	mov    %eax,-0x24(%ebp)
f0101814:	85 c0                	test   %eax,%eax
f0101816:	0f 84 89 00 00 00    	je     f01018a5 <i386_vm_init+0x187>
}

static inline physaddr_t
page2pa(struct Page *pp)
{
	return page2ppn(pp) << PGSHIFT;
f010181c:	2b 05 2c ff 2c f0    	sub    0xf02cff2c,%eax
f0101822:	c1 f8 02             	sar    $0x2,%eax
f0101825:	69 c0 ab aa aa aa    	imul   $0xaaaaaaab,%eax,%eax
f010182b:	c1 e0 0c             	shl    $0xc,%eax
}

static inline void*
page2kva(struct Page *pp)
{
	return KADDR(page2pa(pp));
f010182e:	89 c2                	mov    %eax,%edx
f0101830:	c1 ea 0c             	shr    $0xc,%edx
f0101833:	3b 15 20 ff 2c f0    	cmp    0xf02cff20,%edx
f0101839:	72 41                	jb     f010187c <i386_vm_init+0x15e>
f010183b:	eb 1f                	jmp    f010185c <i386_vm_init+0x13e>
}

static inline physaddr_t
page2pa(struct Page *pp)
{
	return page2ppn(pp) << PGSHIFT;
f010183d:	2b 05 2c ff 2c f0    	sub    0xf02cff2c,%eax
f0101843:	c1 f8 02             	sar    $0x2,%eax
f0101846:	69 c0 ab aa aa aa    	imul   $0xaaaaaaab,%eax,%eax
f010184c:	c1 e0 0c             	shl    $0xc,%eax
}

static inline void*
page2kva(struct Page *pp)
{
	return KADDR(page2pa(pp));
f010184f:	89 c2                	mov    %eax,%edx
f0101851:	c1 ea 0c             	shr    $0xc,%edx
f0101854:	3b 15 20 ff 2c f0    	cmp    0xf02cff20,%edx
f010185a:	72 20                	jb     f010187c <i386_vm_init+0x15e>
f010185c:	89 44 24 0c          	mov    %eax,0xc(%esp)
f0101860:	c7 44 24 08 50 70 10 	movl   $0xf0107050,0x8(%esp)
f0101867:	f0 
f0101868:	c7 44 24 04 5a 00 00 	movl   $0x5a,0x4(%esp)
f010186f:	00 
f0101870:	c7 04 24 7d 6c 10 f0 	movl   $0xf0106c7d,(%esp)
f0101877:	e8 09 e8 ff ff       	call   f0100085 <_panic>
		memset(page2kva(pp0), 0x97, sizeof(struct Page));
f010187c:	c7 44 24 08 0c 00 00 	movl   $0xc,0x8(%esp)
f0101883:	00 
f0101884:	c7 44 24 04 97 00 00 	movl   $0x97,0x4(%esp)
f010188b:	00 
f010188c:	2d 00 00 00 10       	sub    $0x10000000,%eax
f0101891:	89 04 24             	mov    %eax,(%esp)
f0101894:	e8 0d 42 00 00       	call   f0105aa6 <memset>
	struct Page_list fl;

	// if there's a page that shouldn't be on
	// the free list, try to make sure it
	// eventually causes trouble.
	LIST_FOREACH(pp0, &page_free_list, pp_link) 
f0101899:	8b 45 dc             	mov    -0x24(%ebp),%eax
f010189c:	8b 00                	mov    (%eax),%eax
f010189e:	89 45 dc             	mov    %eax,-0x24(%ebp)
f01018a1:	85 c0                	test   %eax,%eax
f01018a3:	75 98                	jne    f010183d <i386_vm_init+0x11f>
		memset(page2kva(pp0), 0x97, sizeof(struct Page));

	LIST_FOREACH(pp0, &page_free_list, pp_link) {
f01018a5:	a1 1c ff 2c f0       	mov    0xf02cff1c,%eax
f01018aa:	89 45 dc             	mov    %eax,-0x24(%ebp)
f01018ad:	85 c0                	test   %eax,%eax
f01018af:	0f 84 e5 01 00 00    	je     f0101a9a <i386_vm_init+0x37c>
		// check that we didn't corrupt the free list itself
		assert(pp0 >= pages);
f01018b5:	8b 1d 2c ff 2c f0    	mov    0xf02cff2c,%ebx
f01018bb:	39 d8                	cmp    %ebx,%eax
f01018bd:	72 5b                	jb     f010191a <i386_vm_init+0x1fc>
		assert(pp0 < pages + npage);
f01018bf:	8b 35 20 ff 2c f0    	mov    0xf02cff20,%esi
f01018c5:	8d 14 76             	lea    (%esi,%esi,2),%edx
f01018c8:	8d 3c 93             	lea    (%ebx,%edx,4),%edi
f01018cb:	39 f8                	cmp    %edi,%eax
f01018cd:	73 73                	jae    f0101942 <i386_vm_init+0x224>
void user_mem_assert(struct Env *env, const void *va, size_t len, int perm);

static inline ppn_t
page2ppn(struct Page *pp)
{
	return pp - pages;
f01018cf:	89 5d c0             	mov    %ebx,-0x40(%ebp)
}

static inline physaddr_t
page2pa(struct Page *pp)
{
	return page2ppn(pp) << PGSHIFT;
f01018d2:	89 c2                	mov    %eax,%edx
f01018d4:	29 da                	sub    %ebx,%edx
f01018d6:	c1 fa 02             	sar    $0x2,%edx
f01018d9:	69 d2 ab aa aa aa    	imul   $0xaaaaaaab,%edx,%edx
f01018df:	c1 e2 0c             	shl    $0xc,%edx

		// check a few pages that shouldn't be on the free list
		assert(page2pa(pp0) != 0);
f01018e2:	85 d2                	test   %edx,%edx
f01018e4:	0f 84 91 00 00 00    	je     f010197b <i386_vm_init+0x25d>
		assert(page2pa(pp0) != IOPHYSMEM);
f01018ea:	81 fa 00 00 0a 00    	cmp    $0xa0000,%edx
f01018f0:	0f 84 b1 00 00 00    	je     f01019a7 <i386_vm_init+0x289>
		assert(page2pa(pp0) != EXTPHYSMEM - PGSIZE);
f01018f6:	81 fa 00 f0 0f 00    	cmp    $0xff000,%edx
f01018fc:	0f 84 d1 00 00 00    	je     f01019d3 <i386_vm_init+0x2b5>
		assert(page2pa(pp0) != EXTPHYSMEM);
f0101902:	81 fa 00 00 10 00    	cmp    $0x100000,%edx
f0101908:	0f 85 15 01 00 00    	jne    f0101a23 <i386_vm_init+0x305>
f010190e:	66 90                	xchg   %ax,%ax
f0101910:	e9 ea 00 00 00       	jmp    f01019ff <i386_vm_init+0x2e1>
	LIST_FOREACH(pp0, &page_free_list, pp_link) 
		memset(page2kva(pp0), 0x97, sizeof(struct Page));

	LIST_FOREACH(pp0, &page_free_list, pp_link) {
		// check that we didn't corrupt the free list itself
		assert(pp0 >= pages);
f0101915:	39 d8                	cmp    %ebx,%eax
f0101917:	90                   	nop
f0101918:	73 24                	jae    f010193e <i386_vm_init+0x220>
f010191a:	c7 44 24 0c 73 76 10 	movl   $0xf0107673,0xc(%esp)
f0101921:	f0 
f0101922:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0101929:	f0 
f010192a:	c7 44 24 04 4a 01 00 	movl   $0x14a,0x4(%esp)
f0101931:	00 
f0101932:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0101939:	e8 47 e7 ff ff       	call   f0100085 <_panic>
		assert(pp0 < pages + npage);
f010193e:	39 f8                	cmp    %edi,%eax
f0101940:	72 24                	jb     f0101966 <i386_vm_init+0x248>
f0101942:	c7 44 24 0c 80 76 10 	movl   $0xf0107680,0xc(%esp)
f0101949:	f0 
f010194a:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0101951:	f0 
f0101952:	c7 44 24 04 4b 01 00 	movl   $0x14b,0x4(%esp)
f0101959:	00 
f010195a:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0101961:	e8 1f e7 ff ff       	call   f0100085 <_panic>
f0101966:	89 c2                	mov    %eax,%edx
f0101968:	2b 55 c0             	sub    -0x40(%ebp),%edx
f010196b:	c1 fa 02             	sar    $0x2,%edx
f010196e:	69 d2 ab aa aa aa    	imul   $0xaaaaaaab,%edx,%edx
f0101974:	c1 e2 0c             	shl    $0xc,%edx

		// check a few pages that shouldn't be on the free list
		assert(page2pa(pp0) != 0);
f0101977:	85 d2                	test   %edx,%edx
f0101979:	75 24                	jne    f010199f <i386_vm_init+0x281>
f010197b:	c7 44 24 0c 94 76 10 	movl   $0xf0107694,0xc(%esp)
f0101982:	f0 
f0101983:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f010198a:	f0 
f010198b:	c7 44 24 04 4e 01 00 	movl   $0x14e,0x4(%esp)
f0101992:	00 
f0101993:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f010199a:	e8 e6 e6 ff ff       	call   f0100085 <_panic>
		assert(page2pa(pp0) != IOPHYSMEM);
f010199f:	81 fa 00 00 0a 00    	cmp    $0xa0000,%edx
f01019a5:	75 24                	jne    f01019cb <i386_vm_init+0x2ad>
f01019a7:	c7 44 24 0c a6 76 10 	movl   $0xf01076a6,0xc(%esp)
f01019ae:	f0 
f01019af:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f01019b6:	f0 
f01019b7:	c7 44 24 04 4f 01 00 	movl   $0x14f,0x4(%esp)
f01019be:	00 
f01019bf:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f01019c6:	e8 ba e6 ff ff       	call   f0100085 <_panic>
		assert(page2pa(pp0) != EXTPHYSMEM - PGSIZE);
f01019cb:	81 fa 00 f0 0f 00    	cmp    $0xff000,%edx
f01019d1:	75 24                	jne    f01019f7 <i386_vm_init+0x2d9>
f01019d3:	c7 44 24 0c f4 70 10 	movl   $0xf01070f4,0xc(%esp)
f01019da:	f0 
f01019db:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f01019e2:	f0 
f01019e3:	c7 44 24 04 50 01 00 	movl   $0x150,0x4(%esp)
f01019ea:	00 
f01019eb:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f01019f2:	e8 8e e6 ff ff       	call   f0100085 <_panic>
		assert(page2pa(pp0) != EXTPHYSMEM);
f01019f7:	81 fa 00 00 10 00    	cmp    $0x100000,%edx
f01019fd:	75 36                	jne    f0101a35 <i386_vm_init+0x317>
f01019ff:	c7 44 24 0c c0 76 10 	movl   $0xf01076c0,0xc(%esp)
f0101a06:	f0 
f0101a07:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0101a0e:	f0 
f0101a0f:	c7 44 24 04 51 01 00 	movl   $0x151,0x4(%esp)
f0101a16:	00 
f0101a17:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0101a1e:	e8 62 e6 ff ff       	call   f0100085 <_panic>
		assert(page2kva(pp0) != ROUNDDOWN(boot_freemem - 1, PGSIZE));
f0101a23:	8b 0d 54 f2 2c f0    	mov    0xf02cf254,%ecx
f0101a29:	83 e9 01             	sub    $0x1,%ecx
f0101a2c:	81 e1 00 f0 ff ff    	and    $0xfffff000,%ecx
f0101a32:	89 4d c4             	mov    %ecx,-0x3c(%ebp)
}

static inline void*
page2kva(struct Page *pp)
{
	return KADDR(page2pa(pp));
f0101a35:	89 d1                	mov    %edx,%ecx
f0101a37:	c1 e9 0c             	shr    $0xc,%ecx
f0101a3a:	39 f1                	cmp    %esi,%ecx
f0101a3c:	72 20                	jb     f0101a5e <i386_vm_init+0x340>
f0101a3e:	89 54 24 0c          	mov    %edx,0xc(%esp)
f0101a42:	c7 44 24 08 50 70 10 	movl   $0xf0107050,0x8(%esp)
f0101a49:	f0 
f0101a4a:	c7 44 24 04 5a 00 00 	movl   $0x5a,0x4(%esp)
f0101a51:	00 
f0101a52:	c7 04 24 7d 6c 10 f0 	movl   $0xf0106c7d,(%esp)
f0101a59:	e8 27 e6 ff ff       	call   f0100085 <_panic>
f0101a5e:	81 ea 00 00 00 10    	sub    $0x10000000,%edx
f0101a64:	39 55 c4             	cmp    %edx,-0x3c(%ebp)
f0101a67:	75 24                	jne    f0101a8d <i386_vm_init+0x36f>
f0101a69:	c7 44 24 0c 18 71 10 	movl   $0xf0107118,0xc(%esp)
f0101a70:	f0 
f0101a71:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0101a78:	f0 
f0101a79:	c7 44 24 04 52 01 00 	movl   $0x152,0x4(%esp)
f0101a80:	00 
f0101a81:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0101a88:	e8 f8 e5 ff ff       	call   f0100085 <_panic>
	// the free list, try to make sure it
	// eventually causes trouble.
	LIST_FOREACH(pp0, &page_free_list, pp_link) 
		memset(page2kva(pp0), 0x97, sizeof(struct Page));

	LIST_FOREACH(pp0, &page_free_list, pp_link) {
f0101a8d:	8b 00                	mov    (%eax),%eax
f0101a8f:	89 45 dc             	mov    %eax,-0x24(%ebp)
f0101a92:	85 c0                	test   %eax,%eax
f0101a94:	0f 85 7b fe ff ff    	jne    f0101915 <i386_vm_init+0x1f7>
		assert(page2pa(pp0) != EXTPHYSMEM);
		assert(page2kva(pp0) != ROUNDDOWN(boot_freemem - 1, PGSIZE));
	}

	// should be able to allocate three pages
	pp0 = pp1 = pp2 = 0;
f0101a9a:	c7 45 e4 00 00 00 00 	movl   $0x0,-0x1c(%ebp)
f0101aa1:	c7 45 e0 00 00 00 00 	movl   $0x0,-0x20(%ebp)
f0101aa8:	c7 45 dc 00 00 00 00 	movl   $0x0,-0x24(%ebp)
	assert(page_alloc(&pp0) == 0);
f0101aaf:	8d 45 dc             	lea    -0x24(%ebp),%eax
f0101ab2:	89 04 24             	mov    %eax,(%esp)
f0101ab5:	e8 11 f6 ff ff       	call   f01010cb <page_alloc>
f0101aba:	85 c0                	test   %eax,%eax
f0101abc:	74 24                	je     f0101ae2 <i386_vm_init+0x3c4>
f0101abe:	c7 44 24 0c db 76 10 	movl   $0xf01076db,0xc(%esp)
f0101ac5:	f0 
f0101ac6:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0101acd:	f0 
f0101ace:	c7 44 24 04 57 01 00 	movl   $0x157,0x4(%esp)
f0101ad5:	00 
f0101ad6:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0101add:	e8 a3 e5 ff ff       	call   f0100085 <_panic>
	assert(page_alloc(&pp1) == 0);
f0101ae2:	8d 45 e0             	lea    -0x20(%ebp),%eax
f0101ae5:	89 04 24             	mov    %eax,(%esp)
f0101ae8:	e8 de f5 ff ff       	call   f01010cb <page_alloc>
f0101aed:	85 c0                	test   %eax,%eax
f0101aef:	74 24                	je     f0101b15 <i386_vm_init+0x3f7>
f0101af1:	c7 44 24 0c f1 76 10 	movl   $0xf01076f1,0xc(%esp)
f0101af8:	f0 
f0101af9:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0101b00:	f0 
f0101b01:	c7 44 24 04 58 01 00 	movl   $0x158,0x4(%esp)
f0101b08:	00 
f0101b09:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0101b10:	e8 70 e5 ff ff       	call   f0100085 <_panic>
	assert(page_alloc(&pp2) == 0);
f0101b15:	8d 45 e4             	lea    -0x1c(%ebp),%eax
f0101b18:	89 04 24             	mov    %eax,(%esp)
f0101b1b:	e8 ab f5 ff ff       	call   f01010cb <page_alloc>
f0101b20:	85 c0                	test   %eax,%eax
f0101b22:	74 24                	je     f0101b48 <i386_vm_init+0x42a>
f0101b24:	c7 44 24 0c 07 77 10 	movl   $0xf0107707,0xc(%esp)
f0101b2b:	f0 
f0101b2c:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0101b33:	f0 
f0101b34:	c7 44 24 04 59 01 00 	movl   $0x159,0x4(%esp)
f0101b3b:	00 
f0101b3c:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0101b43:	e8 3d e5 ff ff       	call   f0100085 <_panic>

	assert(pp0);
f0101b48:	8b 4d dc             	mov    -0x24(%ebp),%ecx
f0101b4b:	85 c9                	test   %ecx,%ecx
f0101b4d:	75 24                	jne    f0101b73 <i386_vm_init+0x455>
f0101b4f:	c7 44 24 0c 2b 77 10 	movl   $0xf010772b,0xc(%esp)
f0101b56:	f0 
f0101b57:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0101b5e:	f0 
f0101b5f:	c7 44 24 04 5b 01 00 	movl   $0x15b,0x4(%esp)
f0101b66:	00 
f0101b67:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0101b6e:	e8 12 e5 ff ff       	call   f0100085 <_panic>
	assert(pp1 && pp1 != pp0);
f0101b73:	8b 55 e0             	mov    -0x20(%ebp),%edx
f0101b76:	85 d2                	test   %edx,%edx
f0101b78:	74 04                	je     f0101b7e <i386_vm_init+0x460>
f0101b7a:	39 d1                	cmp    %edx,%ecx
f0101b7c:	75 24                	jne    f0101ba2 <i386_vm_init+0x484>
f0101b7e:	c7 44 24 0c 1d 77 10 	movl   $0xf010771d,0xc(%esp)
f0101b85:	f0 
f0101b86:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0101b8d:	f0 
f0101b8e:	c7 44 24 04 5c 01 00 	movl   $0x15c,0x4(%esp)
f0101b95:	00 
f0101b96:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0101b9d:	e8 e3 e4 ff ff       	call   f0100085 <_panic>
	assert(pp2 && pp2 != pp1 && pp2 != pp0);
f0101ba2:	8b 45 e4             	mov    -0x1c(%ebp),%eax
f0101ba5:	85 c0                	test   %eax,%eax
f0101ba7:	74 09                	je     f0101bb2 <i386_vm_init+0x494>
f0101ba9:	39 c2                	cmp    %eax,%edx
f0101bab:	74 05                	je     f0101bb2 <i386_vm_init+0x494>
f0101bad:	39 c1                	cmp    %eax,%ecx
f0101baf:	90                   	nop
f0101bb0:	75 24                	jne    f0101bd6 <i386_vm_init+0x4b8>
f0101bb2:	c7 44 24 0c 50 71 10 	movl   $0xf0107150,0xc(%esp)
f0101bb9:	f0 
f0101bba:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0101bc1:	f0 
f0101bc2:	c7 44 24 04 5d 01 00 	movl   $0x15d,0x4(%esp)
f0101bc9:	00 
f0101bca:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0101bd1:	e8 af e4 ff ff       	call   f0100085 <_panic>
void user_mem_assert(struct Env *env, const void *va, size_t len, int perm);

static inline ppn_t
page2ppn(struct Page *pp)
{
	return pp - pages;
f0101bd6:	8b 35 2c ff 2c f0    	mov    0xf02cff2c,%esi
	assert(page2pa(pp0) < npage*PGSIZE);
f0101bdc:	8b 1d 20 ff 2c f0    	mov    0xf02cff20,%ebx
f0101be2:	c1 e3 0c             	shl    $0xc,%ebx
f0101be5:	29 f1                	sub    %esi,%ecx
f0101be7:	c1 f9 02             	sar    $0x2,%ecx
f0101bea:	69 c9 ab aa aa aa    	imul   $0xaaaaaaab,%ecx,%ecx
f0101bf0:	c1 e1 0c             	shl    $0xc,%ecx
f0101bf3:	39 d9                	cmp    %ebx,%ecx
f0101bf5:	72 24                	jb     f0101c1b <i386_vm_init+0x4fd>
f0101bf7:	c7 44 24 0c 2f 77 10 	movl   $0xf010772f,0xc(%esp)
f0101bfe:	f0 
f0101bff:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0101c06:	f0 
f0101c07:	c7 44 24 04 5e 01 00 	movl   $0x15e,0x4(%esp)
f0101c0e:	00 
f0101c0f:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0101c16:	e8 6a e4 ff ff       	call   f0100085 <_panic>
	assert(page2pa(pp1) < npage*PGSIZE);
f0101c1b:	29 f2                	sub    %esi,%edx
f0101c1d:	c1 fa 02             	sar    $0x2,%edx
f0101c20:	69 d2 ab aa aa aa    	imul   $0xaaaaaaab,%edx,%edx
f0101c26:	c1 e2 0c             	shl    $0xc,%edx
f0101c29:	39 d3                	cmp    %edx,%ebx
f0101c2b:	77 24                	ja     f0101c51 <i386_vm_init+0x533>
f0101c2d:	c7 44 24 0c 4b 77 10 	movl   $0xf010774b,0xc(%esp)
f0101c34:	f0 
f0101c35:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0101c3c:	f0 
f0101c3d:	c7 44 24 04 5f 01 00 	movl   $0x15f,0x4(%esp)
f0101c44:	00 
f0101c45:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0101c4c:	e8 34 e4 ff ff       	call   f0100085 <_panic>
	assert(page2pa(pp2) < npage*PGSIZE);
f0101c51:	29 f0                	sub    %esi,%eax
f0101c53:	c1 f8 02             	sar    $0x2,%eax
f0101c56:	69 c0 ab aa aa aa    	imul   $0xaaaaaaab,%eax,%eax
f0101c5c:	c1 e0 0c             	shl    $0xc,%eax
f0101c5f:	39 c3                	cmp    %eax,%ebx
f0101c61:	77 24                	ja     f0101c87 <i386_vm_init+0x569>
f0101c63:	c7 44 24 0c 67 77 10 	movl   $0xf0107767,0xc(%esp)
f0101c6a:	f0 
f0101c6b:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0101c72:	f0 
f0101c73:	c7 44 24 04 60 01 00 	movl   $0x160,0x4(%esp)
f0101c7a:	00 
f0101c7b:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0101c82:	e8 fe e3 ff ff       	call   f0100085 <_panic>

	// temporarily steal the rest of the free pages
	fl = page_free_list;
f0101c87:	8b 1d 1c ff 2c f0    	mov    0xf02cff1c,%ebx
	LIST_INIT(&page_free_list);
f0101c8d:	c7 05 1c ff 2c f0 00 	movl   $0x0,0xf02cff1c
f0101c94:	00 00 00 

	// should be no free memory
	assert(page_alloc(&pp) == -E_NO_MEM);
f0101c97:	8d 45 d8             	lea    -0x28(%ebp),%eax
f0101c9a:	89 04 24             	mov    %eax,(%esp)
f0101c9d:	e8 29 f4 ff ff       	call   f01010cb <page_alloc>
f0101ca2:	83 f8 fc             	cmp    $0xfffffffc,%eax
f0101ca5:	74 24                	je     f0101ccb <i386_vm_init+0x5ad>
f0101ca7:	c7 44 24 0c 83 77 10 	movl   $0xf0107783,0xc(%esp)
f0101cae:	f0 
f0101caf:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0101cb6:	f0 
f0101cb7:	c7 44 24 04 67 01 00 	movl   $0x167,0x4(%esp)
f0101cbe:	00 
f0101cbf:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0101cc6:	e8 ba e3 ff ff       	call   f0100085 <_panic>

	// free and re-allocate?
	page_free(pp0);
f0101ccb:	8b 45 dc             	mov    -0x24(%ebp),%eax
f0101cce:	89 04 24             	mov    %eax,(%esp)
f0101cd1:	e8 a9 f2 ff ff       	call   f0100f7f <page_free>
	page_free(pp1);
f0101cd6:	8b 45 e0             	mov    -0x20(%ebp),%eax
f0101cd9:	89 04 24             	mov    %eax,(%esp)
f0101cdc:	e8 9e f2 ff ff       	call   f0100f7f <page_free>
	page_free(pp2);
f0101ce1:	8b 45 e4             	mov    -0x1c(%ebp),%eax
f0101ce4:	89 04 24             	mov    %eax,(%esp)
f0101ce7:	e8 93 f2 ff ff       	call   f0100f7f <page_free>
	pp0 = pp1 = pp2 = 0;
f0101cec:	c7 45 e4 00 00 00 00 	movl   $0x0,-0x1c(%ebp)
f0101cf3:	c7 45 e0 00 00 00 00 	movl   $0x0,-0x20(%ebp)
f0101cfa:	c7 45 dc 00 00 00 00 	movl   $0x0,-0x24(%ebp)
	assert(page_alloc(&pp0) == 0);
f0101d01:	8d 45 dc             	lea    -0x24(%ebp),%eax
f0101d04:	89 04 24             	mov    %eax,(%esp)
f0101d07:	e8 bf f3 ff ff       	call   f01010cb <page_alloc>
f0101d0c:	85 c0                	test   %eax,%eax
f0101d0e:	74 24                	je     f0101d34 <i386_vm_init+0x616>
f0101d10:	c7 44 24 0c db 76 10 	movl   $0xf01076db,0xc(%esp)
f0101d17:	f0 
f0101d18:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0101d1f:	f0 
f0101d20:	c7 44 24 04 6e 01 00 	movl   $0x16e,0x4(%esp)
f0101d27:	00 
f0101d28:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0101d2f:	e8 51 e3 ff ff       	call   f0100085 <_panic>
	assert(page_alloc(&pp1) == 0);
f0101d34:	8d 45 e0             	lea    -0x20(%ebp),%eax
f0101d37:	89 04 24             	mov    %eax,(%esp)
f0101d3a:	e8 8c f3 ff ff       	call   f01010cb <page_alloc>
f0101d3f:	85 c0                	test   %eax,%eax
f0101d41:	74 24                	je     f0101d67 <i386_vm_init+0x649>
f0101d43:	c7 44 24 0c f1 76 10 	movl   $0xf01076f1,0xc(%esp)
f0101d4a:	f0 
f0101d4b:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0101d52:	f0 
f0101d53:	c7 44 24 04 6f 01 00 	movl   $0x16f,0x4(%esp)
f0101d5a:	00 
f0101d5b:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0101d62:	e8 1e e3 ff ff       	call   f0100085 <_panic>
	assert(page_alloc(&pp2) == 0);
f0101d67:	8d 45 e4             	lea    -0x1c(%ebp),%eax
f0101d6a:	89 04 24             	mov    %eax,(%esp)
f0101d6d:	e8 59 f3 ff ff       	call   f01010cb <page_alloc>
f0101d72:	85 c0                	test   %eax,%eax
f0101d74:	74 24                	je     f0101d9a <i386_vm_init+0x67c>
f0101d76:	c7 44 24 0c 07 77 10 	movl   $0xf0107707,0xc(%esp)
f0101d7d:	f0 
f0101d7e:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0101d85:	f0 
f0101d86:	c7 44 24 04 70 01 00 	movl   $0x170,0x4(%esp)
f0101d8d:	00 
f0101d8e:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0101d95:	e8 eb e2 ff ff       	call   f0100085 <_panic>
	assert(pp0);
f0101d9a:	8b 55 dc             	mov    -0x24(%ebp),%edx
f0101d9d:	85 d2                	test   %edx,%edx
f0101d9f:	75 24                	jne    f0101dc5 <i386_vm_init+0x6a7>
f0101da1:	c7 44 24 0c 2b 77 10 	movl   $0xf010772b,0xc(%esp)
f0101da8:	f0 
f0101da9:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0101db0:	f0 
f0101db1:	c7 44 24 04 71 01 00 	movl   $0x171,0x4(%esp)
f0101db8:	00 
f0101db9:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0101dc0:	e8 c0 e2 ff ff       	call   f0100085 <_panic>
	assert(pp1 && pp1 != pp0);
f0101dc5:	8b 4d e0             	mov    -0x20(%ebp),%ecx
f0101dc8:	85 c9                	test   %ecx,%ecx
f0101dca:	74 04                	je     f0101dd0 <i386_vm_init+0x6b2>
f0101dcc:	39 ca                	cmp    %ecx,%edx
f0101dce:	75 24                	jne    f0101df4 <i386_vm_init+0x6d6>
f0101dd0:	c7 44 24 0c 1d 77 10 	movl   $0xf010771d,0xc(%esp)
f0101dd7:	f0 
f0101dd8:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0101ddf:	f0 
f0101de0:	c7 44 24 04 72 01 00 	movl   $0x172,0x4(%esp)
f0101de7:	00 
f0101de8:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0101def:	e8 91 e2 ff ff       	call   f0100085 <_panic>
	assert(pp2 && pp2 != pp1 && pp2 != pp0);
f0101df4:	8b 45 e4             	mov    -0x1c(%ebp),%eax
f0101df7:	85 c0                	test   %eax,%eax
f0101df9:	74 08                	je     f0101e03 <i386_vm_init+0x6e5>
f0101dfb:	39 c1                	cmp    %eax,%ecx
f0101dfd:	74 04                	je     f0101e03 <i386_vm_init+0x6e5>
f0101dff:	39 c2                	cmp    %eax,%edx
f0101e01:	75 24                	jne    f0101e27 <i386_vm_init+0x709>
f0101e03:	c7 44 24 0c 50 71 10 	movl   $0xf0107150,0xc(%esp)
f0101e0a:	f0 
f0101e0b:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0101e12:	f0 
f0101e13:	c7 44 24 04 73 01 00 	movl   $0x173,0x4(%esp)
f0101e1a:	00 
f0101e1b:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0101e22:	e8 5e e2 ff ff       	call   f0100085 <_panic>
	assert(page_alloc(&pp) == -E_NO_MEM);
f0101e27:	8d 45 d8             	lea    -0x28(%ebp),%eax
f0101e2a:	89 04 24             	mov    %eax,(%esp)
f0101e2d:	e8 99 f2 ff ff       	call   f01010cb <page_alloc>
f0101e32:	83 f8 fc             	cmp    $0xfffffffc,%eax
f0101e35:	74 24                	je     f0101e5b <i386_vm_init+0x73d>
f0101e37:	c7 44 24 0c 83 77 10 	movl   $0xf0107783,0xc(%esp)
f0101e3e:	f0 
f0101e3f:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0101e46:	f0 
f0101e47:	c7 44 24 04 74 01 00 	movl   $0x174,0x4(%esp)
f0101e4e:	00 
f0101e4f:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0101e56:	e8 2a e2 ff ff       	call   f0100085 <_panic>

	// give free list back
	page_free_list = fl;
f0101e5b:	89 1d 1c ff 2c f0    	mov    %ebx,0xf02cff1c

	// free the pages we took
	page_free(pp0);
f0101e61:	8b 45 dc             	mov    -0x24(%ebp),%eax
f0101e64:	89 04 24             	mov    %eax,(%esp)
f0101e67:	e8 13 f1 ff ff       	call   f0100f7f <page_free>
	page_free(pp1);
f0101e6c:	8b 45 e0             	mov    -0x20(%ebp),%eax
f0101e6f:	89 04 24             	mov    %eax,(%esp)
f0101e72:	e8 08 f1 ff ff       	call   f0100f7f <page_free>
	page_free(pp2);
f0101e77:	8b 45 e4             	mov    -0x1c(%ebp),%eax
f0101e7a:	89 04 24             	mov    %eax,(%esp)
f0101e7d:	e8 fd f0 ff ff       	call   f0100f7f <page_free>

	cprintf("check_page_alloc() succeeded!\n");
f0101e82:	c7 04 24 70 71 10 f0 	movl   $0xf0107170,(%esp)
f0101e89:	e8 51 1b 00 00       	call   f01039df <cprintf>
	pte_t *ptep, *ptep1;
	void *va;
	int i;

	// should be able to allocate three pages
	pp0 = pp1 = pp2 = 0;
f0101e8e:	c7 45 d8 00 00 00 00 	movl   $0x0,-0x28(%ebp)
f0101e95:	c7 45 dc 00 00 00 00 	movl   $0x0,-0x24(%ebp)
f0101e9c:	c7 45 e0 00 00 00 00 	movl   $0x0,-0x20(%ebp)
	assert(page_alloc(&pp0) == 0);
f0101ea3:	8d 45 e0             	lea    -0x20(%ebp),%eax
f0101ea6:	89 04 24             	mov    %eax,(%esp)
f0101ea9:	e8 1d f2 ff ff       	call   f01010cb <page_alloc>
f0101eae:	85 c0                	test   %eax,%eax
f0101eb0:	74 24                	je     f0101ed6 <i386_vm_init+0x7b8>
f0101eb2:	c7 44 24 0c db 76 10 	movl   $0xf01076db,0xc(%esp)
f0101eb9:	f0 
f0101eba:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0101ec1:	f0 
f0101ec2:	c7 44 24 04 3e 03 00 	movl   $0x33e,0x4(%esp)
f0101ec9:	00 
f0101eca:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0101ed1:	e8 af e1 ff ff       	call   f0100085 <_panic>
	assert(page_alloc(&pp1) == 0);
f0101ed6:	8d 45 dc             	lea    -0x24(%ebp),%eax
f0101ed9:	89 04 24             	mov    %eax,(%esp)
f0101edc:	e8 ea f1 ff ff       	call   f01010cb <page_alloc>
f0101ee1:	85 c0                	test   %eax,%eax
f0101ee3:	74 24                	je     f0101f09 <i386_vm_init+0x7eb>
f0101ee5:	c7 44 24 0c f1 76 10 	movl   $0xf01076f1,0xc(%esp)
f0101eec:	f0 
f0101eed:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0101ef4:	f0 
f0101ef5:	c7 44 24 04 3f 03 00 	movl   $0x33f,0x4(%esp)
f0101efc:	00 
f0101efd:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0101f04:	e8 7c e1 ff ff       	call   f0100085 <_panic>
	assert(page_alloc(&pp2) == 0);
f0101f09:	8d 45 d8             	lea    -0x28(%ebp),%eax
f0101f0c:	89 04 24             	mov    %eax,(%esp)
f0101f0f:	e8 b7 f1 ff ff       	call   f01010cb <page_alloc>
f0101f14:	85 c0                	test   %eax,%eax
f0101f16:	74 24                	je     f0101f3c <i386_vm_init+0x81e>
f0101f18:	c7 44 24 0c 07 77 10 	movl   $0xf0107707,0xc(%esp)
f0101f1f:	f0 
f0101f20:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0101f27:	f0 
f0101f28:	c7 44 24 04 40 03 00 	movl   $0x340,0x4(%esp)
f0101f2f:	00 
f0101f30:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0101f37:	e8 49 e1 ff ff       	call   f0100085 <_panic>

	assert(pp0);
f0101f3c:	8b 55 e0             	mov    -0x20(%ebp),%edx
f0101f3f:	85 d2                	test   %edx,%edx
f0101f41:	75 24                	jne    f0101f67 <i386_vm_init+0x849>
f0101f43:	c7 44 24 0c 2b 77 10 	movl   $0xf010772b,0xc(%esp)
f0101f4a:	f0 
f0101f4b:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0101f52:	f0 
f0101f53:	c7 44 24 04 42 03 00 	movl   $0x342,0x4(%esp)
f0101f5a:	00 
f0101f5b:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0101f62:	e8 1e e1 ff ff       	call   f0100085 <_panic>
	assert(pp1 && pp1 != pp0);
f0101f67:	8b 4d dc             	mov    -0x24(%ebp),%ecx
f0101f6a:	85 c9                	test   %ecx,%ecx
f0101f6c:	74 04                	je     f0101f72 <i386_vm_init+0x854>
f0101f6e:	39 ca                	cmp    %ecx,%edx
f0101f70:	75 24                	jne    f0101f96 <i386_vm_init+0x878>
f0101f72:	c7 44 24 0c 1d 77 10 	movl   $0xf010771d,0xc(%esp)
f0101f79:	f0 
f0101f7a:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0101f81:	f0 
f0101f82:	c7 44 24 04 43 03 00 	movl   $0x343,0x4(%esp)
f0101f89:	00 
f0101f8a:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0101f91:	e8 ef e0 ff ff       	call   f0100085 <_panic>
	assert(pp2 && pp2 != pp1 && pp2 != pp0);
f0101f96:	8b 45 d8             	mov    -0x28(%ebp),%eax
f0101f99:	85 c0                	test   %eax,%eax
f0101f9b:	74 08                	je     f0101fa5 <i386_vm_init+0x887>
f0101f9d:	39 c1                	cmp    %eax,%ecx
f0101f9f:	74 04                	je     f0101fa5 <i386_vm_init+0x887>
f0101fa1:	39 c2                	cmp    %eax,%edx
f0101fa3:	75 24                	jne    f0101fc9 <i386_vm_init+0x8ab>
f0101fa5:	c7 44 24 0c 50 71 10 	movl   $0xf0107150,0xc(%esp)
f0101fac:	f0 
f0101fad:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0101fb4:	f0 
f0101fb5:	c7 44 24 04 44 03 00 	movl   $0x344,0x4(%esp)
f0101fbc:	00 
f0101fbd:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0101fc4:	e8 bc e0 ff ff       	call   f0100085 <_panic>

	// temporarily steal the rest of the free pages
	fl = page_free_list;
f0101fc9:	8b 1d 1c ff 2c f0    	mov    0xf02cff1c,%ebx
	LIST_INIT(&page_free_list);
f0101fcf:	c7 05 1c ff 2c f0 00 	movl   $0x0,0xf02cff1c
f0101fd6:	00 00 00 

	// should be no free memory
	assert(page_alloc(&pp) == -E_NO_MEM);
f0101fd9:	8d 45 e4             	lea    -0x1c(%ebp),%eax
f0101fdc:	89 04 24             	mov    %eax,(%esp)
f0101fdf:	e8 e7 f0 ff ff       	call   f01010cb <page_alloc>
f0101fe4:	83 f8 fc             	cmp    $0xfffffffc,%eax
f0101fe7:	74 24                	je     f010200d <i386_vm_init+0x8ef>
f0101fe9:	c7 44 24 0c 83 77 10 	movl   $0xf0107783,0xc(%esp)
f0101ff0:	f0 
f0101ff1:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0101ff8:	f0 
f0101ff9:	c7 44 24 04 4b 03 00 	movl   $0x34b,0x4(%esp)
f0102000:	00 
f0102001:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0102008:	e8 78 e0 ff ff       	call   f0100085 <_panic>

	// there is no page allocated at address 0
	assert(page_lookup(boot_pgdir, (void *) 0x0, &ptep) == NULL);
f010200d:	8d 45 d4             	lea    -0x2c(%ebp),%eax
f0102010:	89 44 24 08          	mov    %eax,0x8(%esp)
f0102014:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
f010201b:	00 
f010201c:	a1 28 ff 2c f0       	mov    0xf02cff28,%eax
f0102021:	89 04 24             	mov    %eax,(%esp)
f0102024:	e8 60 f2 ff ff       	call   f0101289 <page_lookup>
f0102029:	85 c0                	test   %eax,%eax
f010202b:	74 24                	je     f0102051 <i386_vm_init+0x933>
f010202d:	c7 44 24 0c 90 71 10 	movl   $0xf0107190,0xc(%esp)
f0102034:	f0 
f0102035:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f010203c:	f0 
f010203d:	c7 44 24 04 4e 03 00 	movl   $0x34e,0x4(%esp)
f0102044:	00 
f0102045:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f010204c:	e8 34 e0 ff ff       	call   f0100085 <_panic>

	// there is no free memory, so we can't allocate a page table 
	assert(page_insert(boot_pgdir, pp1, 0x0, 0) < 0);
f0102051:	c7 44 24 0c 00 00 00 	movl   $0x0,0xc(%esp)
f0102058:	00 
f0102059:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
f0102060:	00 
f0102061:	8b 45 dc             	mov    -0x24(%ebp),%eax
f0102064:	89 44 24 04          	mov    %eax,0x4(%esp)
f0102068:	a1 28 ff 2c f0       	mov    0xf02cff28,%eax
f010206d:	89 04 24             	mov    %eax,(%esp)
f0102070:	e8 22 f4 ff ff       	call   f0101497 <page_insert>
f0102075:	85 c0                	test   %eax,%eax
f0102077:	78 24                	js     f010209d <i386_vm_init+0x97f>
f0102079:	c7 44 24 0c c8 71 10 	movl   $0xf01071c8,0xc(%esp)
f0102080:	f0 
f0102081:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0102088:	f0 
f0102089:	c7 44 24 04 51 03 00 	movl   $0x351,0x4(%esp)
f0102090:	00 
f0102091:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0102098:	e8 e8 df ff ff       	call   f0100085 <_panic>

	// free pp0 and try again: pp0 should be used for page table
	page_free(pp0);
f010209d:	8b 45 e0             	mov    -0x20(%ebp),%eax
f01020a0:	89 04 24             	mov    %eax,(%esp)
f01020a3:	e8 d7 ee ff ff       	call   f0100f7f <page_free>
	assert(page_insert(boot_pgdir, pp1, 0x0, 0) == 0);
f01020a8:	c7 44 24 0c 00 00 00 	movl   $0x0,0xc(%esp)
f01020af:	00 
f01020b0:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
f01020b7:	00 
f01020b8:	8b 45 dc             	mov    -0x24(%ebp),%eax
f01020bb:	89 44 24 04          	mov    %eax,0x4(%esp)
f01020bf:	a1 28 ff 2c f0       	mov    0xf02cff28,%eax
f01020c4:	89 04 24             	mov    %eax,(%esp)
f01020c7:	e8 cb f3 ff ff       	call   f0101497 <page_insert>
f01020cc:	85 c0                	test   %eax,%eax
f01020ce:	74 24                	je     f01020f4 <i386_vm_init+0x9d6>
f01020d0:	c7 44 24 0c f4 71 10 	movl   $0xf01071f4,0xc(%esp)
f01020d7:	f0 
f01020d8:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f01020df:	f0 
f01020e0:	c7 44 24 04 55 03 00 	movl   $0x355,0x4(%esp)
f01020e7:	00 
f01020e8:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f01020ef:	e8 91 df ff ff       	call   f0100085 <_panic>
	assert(PTE_ADDR(boot_pgdir[0]) == page2pa(pp0));
f01020f4:	a1 28 ff 2c f0       	mov    0xf02cff28,%eax
f01020f9:	8b 08                	mov    (%eax),%ecx
f01020fb:	81 e1 00 f0 ff ff    	and    $0xfffff000,%ecx
f0102101:	8b 55 e0             	mov    -0x20(%ebp),%edx
f0102104:	2b 15 2c ff 2c f0    	sub    0xf02cff2c,%edx
f010210a:	c1 fa 02             	sar    $0x2,%edx
f010210d:	69 d2 ab aa aa aa    	imul   $0xaaaaaaab,%edx,%edx
f0102113:	c1 e2 0c             	shl    $0xc,%edx
f0102116:	39 d1                	cmp    %edx,%ecx
f0102118:	74 24                	je     f010213e <i386_vm_init+0xa20>
f010211a:	c7 44 24 0c 20 72 10 	movl   $0xf0107220,0xc(%esp)
f0102121:	f0 
f0102122:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0102129:	f0 
f010212a:	c7 44 24 04 56 03 00 	movl   $0x356,0x4(%esp)
f0102131:	00 
f0102132:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0102139:	e8 47 df ff ff       	call   f0100085 <_panic>
	assert(check_va2pa(boot_pgdir, 0x0) == page2pa(pp1));
f010213e:	ba 00 00 00 00       	mov    $0x0,%edx
f0102143:	e8 1d ef ff ff       	call   f0101065 <check_va2pa>
f0102148:	8b 55 dc             	mov    -0x24(%ebp),%edx
f010214b:	89 d1                	mov    %edx,%ecx
f010214d:	2b 0d 2c ff 2c f0    	sub    0xf02cff2c,%ecx
f0102153:	c1 f9 02             	sar    $0x2,%ecx
f0102156:	69 c9 ab aa aa aa    	imul   $0xaaaaaaab,%ecx,%ecx
f010215c:	c1 e1 0c             	shl    $0xc,%ecx
f010215f:	39 c8                	cmp    %ecx,%eax
f0102161:	74 24                	je     f0102187 <i386_vm_init+0xa69>
f0102163:	c7 44 24 0c 48 72 10 	movl   $0xf0107248,0xc(%esp)
f010216a:	f0 
f010216b:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0102172:	f0 
f0102173:	c7 44 24 04 57 03 00 	movl   $0x357,0x4(%esp)
f010217a:	00 
f010217b:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0102182:	e8 fe de ff ff       	call   f0100085 <_panic>
	assert(pp1->pp_ref == 1);
f0102187:	66 83 7a 08 01       	cmpw   $0x1,0x8(%edx)
f010218c:	74 24                	je     f01021b2 <i386_vm_init+0xa94>
f010218e:	c7 44 24 0c a0 77 10 	movl   $0xf01077a0,0xc(%esp)
f0102195:	f0 
f0102196:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f010219d:	f0 
f010219e:	c7 44 24 04 58 03 00 	movl   $0x358,0x4(%esp)
f01021a5:	00 
f01021a6:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f01021ad:	e8 d3 de ff ff       	call   f0100085 <_panic>
	assert(pp0->pp_ref == 1);
f01021b2:	8b 45 e0             	mov    -0x20(%ebp),%eax
f01021b5:	66 83 78 08 01       	cmpw   $0x1,0x8(%eax)
f01021ba:	74 24                	je     f01021e0 <i386_vm_init+0xac2>
f01021bc:	c7 44 24 0c b1 77 10 	movl   $0xf01077b1,0xc(%esp)
f01021c3:	f0 
f01021c4:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f01021cb:	f0 
f01021cc:	c7 44 24 04 59 03 00 	movl   $0x359,0x4(%esp)
f01021d3:	00 
f01021d4:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f01021db:	e8 a5 de ff ff       	call   f0100085 <_panic>

	// should be able to map pp2 at PGSIZE because pp0 is already allocated for page table
	assert(page_insert(boot_pgdir, pp2, (void*) PGSIZE, 0) == 0);
f01021e0:	c7 44 24 0c 00 00 00 	movl   $0x0,0xc(%esp)
f01021e7:	00 
f01021e8:	c7 44 24 08 00 10 00 	movl   $0x1000,0x8(%esp)
f01021ef:	00 
f01021f0:	8b 45 d8             	mov    -0x28(%ebp),%eax
f01021f3:	89 44 24 04          	mov    %eax,0x4(%esp)
f01021f7:	a1 28 ff 2c f0       	mov    0xf02cff28,%eax
f01021fc:	89 04 24             	mov    %eax,(%esp)
f01021ff:	e8 93 f2 ff ff       	call   f0101497 <page_insert>
f0102204:	85 c0                	test   %eax,%eax
f0102206:	74 24                	je     f010222c <i386_vm_init+0xb0e>
f0102208:	c7 44 24 0c 78 72 10 	movl   $0xf0107278,0xc(%esp)
f010220f:	f0 
f0102210:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0102217:	f0 
f0102218:	c7 44 24 04 5c 03 00 	movl   $0x35c,0x4(%esp)
f010221f:	00 
f0102220:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0102227:	e8 59 de ff ff       	call   f0100085 <_panic>
	assert(check_va2pa(boot_pgdir, PGSIZE) == page2pa(pp2));
f010222c:	ba 00 10 00 00       	mov    $0x1000,%edx
f0102231:	a1 28 ff 2c f0       	mov    0xf02cff28,%eax
f0102236:	e8 2a ee ff ff       	call   f0101065 <check_va2pa>
f010223b:	8b 55 d8             	mov    -0x28(%ebp),%edx
f010223e:	89 d1                	mov    %edx,%ecx
f0102240:	2b 0d 2c ff 2c f0    	sub    0xf02cff2c,%ecx
f0102246:	c1 f9 02             	sar    $0x2,%ecx
f0102249:	69 c9 ab aa aa aa    	imul   $0xaaaaaaab,%ecx,%ecx
f010224f:	c1 e1 0c             	shl    $0xc,%ecx
f0102252:	39 c8                	cmp    %ecx,%eax
f0102254:	74 24                	je     f010227a <i386_vm_init+0xb5c>
f0102256:	c7 44 24 0c b0 72 10 	movl   $0xf01072b0,0xc(%esp)
f010225d:	f0 
f010225e:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0102265:	f0 
f0102266:	c7 44 24 04 5d 03 00 	movl   $0x35d,0x4(%esp)
f010226d:	00 
f010226e:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0102275:	e8 0b de ff ff       	call   f0100085 <_panic>
	assert(pp2->pp_ref == 1);
f010227a:	66 83 7a 08 01       	cmpw   $0x1,0x8(%edx)
f010227f:	74 24                	je     f01022a5 <i386_vm_init+0xb87>
f0102281:	c7 44 24 0c c2 77 10 	movl   $0xf01077c2,0xc(%esp)
f0102288:	f0 
f0102289:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0102290:	f0 
f0102291:	c7 44 24 04 5e 03 00 	movl   $0x35e,0x4(%esp)
f0102298:	00 
f0102299:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f01022a0:	e8 e0 dd ff ff       	call   f0100085 <_panic>

	// should be no free memory
	assert(page_alloc(&pp) == -E_NO_MEM);
f01022a5:	8d 45 e4             	lea    -0x1c(%ebp),%eax
f01022a8:	89 04 24             	mov    %eax,(%esp)
f01022ab:	e8 1b ee ff ff       	call   f01010cb <page_alloc>
f01022b0:	83 f8 fc             	cmp    $0xfffffffc,%eax
f01022b3:	74 24                	je     f01022d9 <i386_vm_init+0xbbb>
f01022b5:	c7 44 24 0c 83 77 10 	movl   $0xf0107783,0xc(%esp)
f01022bc:	f0 
f01022bd:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f01022c4:	f0 
f01022c5:	c7 44 24 04 61 03 00 	movl   $0x361,0x4(%esp)
f01022cc:	00 
f01022cd:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f01022d4:	e8 ac dd ff ff       	call   f0100085 <_panic>

	// should be able to map pp2 at PGSIZE because it's already there
	assert(page_insert(boot_pgdir, pp2, (void*) PGSIZE, 0) == 0);
f01022d9:	c7 44 24 0c 00 00 00 	movl   $0x0,0xc(%esp)
f01022e0:	00 
f01022e1:	c7 44 24 08 00 10 00 	movl   $0x1000,0x8(%esp)
f01022e8:	00 
f01022e9:	8b 45 d8             	mov    -0x28(%ebp),%eax
f01022ec:	89 44 24 04          	mov    %eax,0x4(%esp)
f01022f0:	a1 28 ff 2c f0       	mov    0xf02cff28,%eax
f01022f5:	89 04 24             	mov    %eax,(%esp)
f01022f8:	e8 9a f1 ff ff       	call   f0101497 <page_insert>
f01022fd:	85 c0                	test   %eax,%eax
f01022ff:	74 24                	je     f0102325 <i386_vm_init+0xc07>
f0102301:	c7 44 24 0c 78 72 10 	movl   $0xf0107278,0xc(%esp)
f0102308:	f0 
f0102309:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0102310:	f0 
f0102311:	c7 44 24 04 64 03 00 	movl   $0x364,0x4(%esp)
f0102318:	00 
f0102319:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0102320:	e8 60 dd ff ff       	call   f0100085 <_panic>
	assert(check_va2pa(boot_pgdir, PGSIZE) == page2pa(pp2));
f0102325:	ba 00 10 00 00       	mov    $0x1000,%edx
f010232a:	a1 28 ff 2c f0       	mov    0xf02cff28,%eax
f010232f:	e8 31 ed ff ff       	call   f0101065 <check_va2pa>
f0102334:	8b 55 d8             	mov    -0x28(%ebp),%edx
f0102337:	89 d1                	mov    %edx,%ecx
f0102339:	2b 0d 2c ff 2c f0    	sub    0xf02cff2c,%ecx
f010233f:	c1 f9 02             	sar    $0x2,%ecx
f0102342:	69 c9 ab aa aa aa    	imul   $0xaaaaaaab,%ecx,%ecx
f0102348:	c1 e1 0c             	shl    $0xc,%ecx
f010234b:	39 c8                	cmp    %ecx,%eax
f010234d:	74 24                	je     f0102373 <i386_vm_init+0xc55>
f010234f:	c7 44 24 0c b0 72 10 	movl   $0xf01072b0,0xc(%esp)
f0102356:	f0 
f0102357:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f010235e:	f0 
f010235f:	c7 44 24 04 65 03 00 	movl   $0x365,0x4(%esp)
f0102366:	00 
f0102367:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f010236e:	e8 12 dd ff ff       	call   f0100085 <_panic>
	assert(pp2->pp_ref == 1);
f0102373:	66 83 7a 08 01       	cmpw   $0x1,0x8(%edx)
f0102378:	74 24                	je     f010239e <i386_vm_init+0xc80>
f010237a:	c7 44 24 0c c2 77 10 	movl   $0xf01077c2,0xc(%esp)
f0102381:	f0 
f0102382:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0102389:	f0 
f010238a:	c7 44 24 04 66 03 00 	movl   $0x366,0x4(%esp)
f0102391:	00 
f0102392:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0102399:	e8 e7 dc ff ff       	call   f0100085 <_panic>

	// pp2 should NOT be on the free list
	// could happen in ref counts are handled sloppily in page_insert
	assert(page_alloc(&pp) == -E_NO_MEM);
f010239e:	8d 45 e4             	lea    -0x1c(%ebp),%eax
f01023a1:	89 04 24             	mov    %eax,(%esp)
f01023a4:	e8 22 ed ff ff       	call   f01010cb <page_alloc>
f01023a9:	83 f8 fc             	cmp    $0xfffffffc,%eax
f01023ac:	74 24                	je     f01023d2 <i386_vm_init+0xcb4>
f01023ae:	c7 44 24 0c 83 77 10 	movl   $0xf0107783,0xc(%esp)
f01023b5:	f0 
f01023b6:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f01023bd:	f0 
f01023be:	c7 44 24 04 6a 03 00 	movl   $0x36a,0x4(%esp)
f01023c5:	00 
f01023c6:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f01023cd:	e8 b3 dc ff ff       	call   f0100085 <_panic>

	// check that pgdir_walk returns a pointer to the pte
	ptep = KADDR(PTE_ADDR(boot_pgdir[PDX(PGSIZE)]));
f01023d2:	a1 28 ff 2c f0       	mov    0xf02cff28,%eax
f01023d7:	8b 00                	mov    (%eax),%eax
f01023d9:	25 00 f0 ff ff       	and    $0xfffff000,%eax
f01023de:	89 c2                	mov    %eax,%edx
f01023e0:	c1 ea 0c             	shr    $0xc,%edx
f01023e3:	3b 15 20 ff 2c f0    	cmp    0xf02cff20,%edx
f01023e9:	72 20                	jb     f010240b <i386_vm_init+0xced>
f01023eb:	89 44 24 0c          	mov    %eax,0xc(%esp)
f01023ef:	c7 44 24 08 50 70 10 	movl   $0xf0107050,0x8(%esp)
f01023f6:	f0 
f01023f7:	c7 44 24 04 6d 03 00 	movl   $0x36d,0x4(%esp)
f01023fe:	00 
f01023ff:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0102406:	e8 7a dc ff ff       	call   f0100085 <_panic>
f010240b:	2d 00 00 00 10       	sub    $0x10000000,%eax
f0102410:	89 45 d4             	mov    %eax,-0x2c(%ebp)
	assert(pgdir_walk(boot_pgdir, (void*)PGSIZE, 0) == ptep+PTX(PGSIZE));
f0102413:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
f010241a:	00 
f010241b:	c7 44 24 04 00 10 00 	movl   $0x1000,0x4(%esp)
f0102422:	00 
f0102423:	a1 28 ff 2c f0       	mov    0xf02cff28,%eax
f0102428:	89 04 24             	mov    %eax,(%esp)
f010242b:	e8 ec ec ff ff       	call   f010111c <pgdir_walk>
f0102430:	8b 55 d4             	mov    -0x2c(%ebp),%edx
f0102433:	83 c2 04             	add    $0x4,%edx
f0102436:	39 d0                	cmp    %edx,%eax
f0102438:	74 24                	je     f010245e <i386_vm_init+0xd40>
f010243a:	c7 44 24 0c e0 72 10 	movl   $0xf01072e0,0xc(%esp)
f0102441:	f0 
f0102442:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0102449:	f0 
f010244a:	c7 44 24 04 6e 03 00 	movl   $0x36e,0x4(%esp)
f0102451:	00 
f0102452:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0102459:	e8 27 dc ff ff       	call   f0100085 <_panic>

	// should be able to change permissions too.
	assert(page_insert(boot_pgdir, pp2, (void*) PGSIZE, PTE_U) == 0);
f010245e:	c7 44 24 0c 04 00 00 	movl   $0x4,0xc(%esp)
f0102465:	00 
f0102466:	c7 44 24 08 00 10 00 	movl   $0x1000,0x8(%esp)
f010246d:	00 
f010246e:	8b 45 d8             	mov    -0x28(%ebp),%eax
f0102471:	89 44 24 04          	mov    %eax,0x4(%esp)
f0102475:	a1 28 ff 2c f0       	mov    0xf02cff28,%eax
f010247a:	89 04 24             	mov    %eax,(%esp)
f010247d:	e8 15 f0 ff ff       	call   f0101497 <page_insert>
f0102482:	85 c0                	test   %eax,%eax
f0102484:	74 24                	je     f01024aa <i386_vm_init+0xd8c>
f0102486:	c7 44 24 0c 20 73 10 	movl   $0xf0107320,0xc(%esp)
f010248d:	f0 
f010248e:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0102495:	f0 
f0102496:	c7 44 24 04 71 03 00 	movl   $0x371,0x4(%esp)
f010249d:	00 
f010249e:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f01024a5:	e8 db db ff ff       	call   f0100085 <_panic>
	assert(check_va2pa(boot_pgdir, PGSIZE) == page2pa(pp2));
f01024aa:	ba 00 10 00 00       	mov    $0x1000,%edx
f01024af:	a1 28 ff 2c f0       	mov    0xf02cff28,%eax
f01024b4:	e8 ac eb ff ff       	call   f0101065 <check_va2pa>
f01024b9:	8b 55 d8             	mov    -0x28(%ebp),%edx
f01024bc:	89 d1                	mov    %edx,%ecx
f01024be:	2b 0d 2c ff 2c f0    	sub    0xf02cff2c,%ecx
f01024c4:	c1 f9 02             	sar    $0x2,%ecx
f01024c7:	69 c9 ab aa aa aa    	imul   $0xaaaaaaab,%ecx,%ecx
f01024cd:	c1 e1 0c             	shl    $0xc,%ecx
f01024d0:	39 c8                	cmp    %ecx,%eax
f01024d2:	74 24                	je     f01024f8 <i386_vm_init+0xdda>
f01024d4:	c7 44 24 0c b0 72 10 	movl   $0xf01072b0,0xc(%esp)
f01024db:	f0 
f01024dc:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f01024e3:	f0 
f01024e4:	c7 44 24 04 72 03 00 	movl   $0x372,0x4(%esp)
f01024eb:	00 
f01024ec:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f01024f3:	e8 8d db ff ff       	call   f0100085 <_panic>
	assert(pp2->pp_ref == 1);
f01024f8:	66 83 7a 08 01       	cmpw   $0x1,0x8(%edx)
f01024fd:	74 24                	je     f0102523 <i386_vm_init+0xe05>
f01024ff:	c7 44 24 0c c2 77 10 	movl   $0xf01077c2,0xc(%esp)
f0102506:	f0 
f0102507:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f010250e:	f0 
f010250f:	c7 44 24 04 73 03 00 	movl   $0x373,0x4(%esp)
f0102516:	00 
f0102517:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f010251e:	e8 62 db ff ff       	call   f0100085 <_panic>
	assert(*pgdir_walk(boot_pgdir, (void*) PGSIZE, 0) & PTE_U);
f0102523:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
f010252a:	00 
f010252b:	c7 44 24 04 00 10 00 	movl   $0x1000,0x4(%esp)
f0102532:	00 
f0102533:	a1 28 ff 2c f0       	mov    0xf02cff28,%eax
f0102538:	89 04 24             	mov    %eax,(%esp)
f010253b:	e8 dc eb ff ff       	call   f010111c <pgdir_walk>
f0102540:	f6 00 04             	testb  $0x4,(%eax)
f0102543:	75 24                	jne    f0102569 <i386_vm_init+0xe4b>
f0102545:	c7 44 24 0c 5c 73 10 	movl   $0xf010735c,0xc(%esp)
f010254c:	f0 
f010254d:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0102554:	f0 
f0102555:	c7 44 24 04 74 03 00 	movl   $0x374,0x4(%esp)
f010255c:	00 
f010255d:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0102564:	e8 1c db ff ff       	call   f0100085 <_panic>
	assert(boot_pgdir[0] & PTE_U);
f0102569:	a1 28 ff 2c f0       	mov    0xf02cff28,%eax
f010256e:	f6 00 04             	testb  $0x4,(%eax)
f0102571:	75 24                	jne    f0102597 <i386_vm_init+0xe79>
f0102573:	c7 44 24 0c d3 77 10 	movl   $0xf01077d3,0xc(%esp)
f010257a:	f0 
f010257b:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0102582:	f0 
f0102583:	c7 44 24 04 75 03 00 	movl   $0x375,0x4(%esp)
f010258a:	00 
f010258b:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0102592:	e8 ee da ff ff       	call   f0100085 <_panic>
	
	// should not be able to map at PTSIZE because need free page for page table
	assert(page_insert(boot_pgdir, pp0, (void*) PTSIZE, 0) < 0);
f0102597:	c7 44 24 0c 00 00 00 	movl   $0x0,0xc(%esp)
f010259e:	00 
f010259f:	c7 44 24 08 00 00 40 	movl   $0x400000,0x8(%esp)
f01025a6:	00 
f01025a7:	8b 55 e0             	mov    -0x20(%ebp),%edx
f01025aa:	89 54 24 04          	mov    %edx,0x4(%esp)
f01025ae:	89 04 24             	mov    %eax,(%esp)
f01025b1:	e8 e1 ee ff ff       	call   f0101497 <page_insert>
f01025b6:	85 c0                	test   %eax,%eax
f01025b8:	78 24                	js     f01025de <i386_vm_init+0xec0>
f01025ba:	c7 44 24 0c 90 73 10 	movl   $0xf0107390,0xc(%esp)
f01025c1:	f0 
f01025c2:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f01025c9:	f0 
f01025ca:	c7 44 24 04 78 03 00 	movl   $0x378,0x4(%esp)
f01025d1:	00 
f01025d2:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f01025d9:	e8 a7 da ff ff       	call   f0100085 <_panic>

	// insert pp1 at PGSIZE (replacing pp2)
	assert(page_insert(boot_pgdir, pp1, (void*) PGSIZE, 0) == 0);
f01025de:	c7 44 24 0c 00 00 00 	movl   $0x0,0xc(%esp)
f01025e5:	00 
f01025e6:	c7 44 24 08 00 10 00 	movl   $0x1000,0x8(%esp)
f01025ed:	00 
f01025ee:	8b 45 dc             	mov    -0x24(%ebp),%eax
f01025f1:	89 44 24 04          	mov    %eax,0x4(%esp)
f01025f5:	a1 28 ff 2c f0       	mov    0xf02cff28,%eax
f01025fa:	89 04 24             	mov    %eax,(%esp)
f01025fd:	e8 95 ee ff ff       	call   f0101497 <page_insert>
f0102602:	85 c0                	test   %eax,%eax
f0102604:	74 24                	je     f010262a <i386_vm_init+0xf0c>
f0102606:	c7 44 24 0c c4 73 10 	movl   $0xf01073c4,0xc(%esp)
f010260d:	f0 
f010260e:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0102615:	f0 
f0102616:	c7 44 24 04 7b 03 00 	movl   $0x37b,0x4(%esp)
f010261d:	00 
f010261e:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0102625:	e8 5b da ff ff       	call   f0100085 <_panic>
	assert(!(*pgdir_walk(boot_pgdir, (void*) PGSIZE, 0) & PTE_U));
f010262a:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
f0102631:	00 
f0102632:	c7 44 24 04 00 10 00 	movl   $0x1000,0x4(%esp)
f0102639:	00 
f010263a:	a1 28 ff 2c f0       	mov    0xf02cff28,%eax
f010263f:	89 04 24             	mov    %eax,(%esp)
f0102642:	e8 d5 ea ff ff       	call   f010111c <pgdir_walk>
f0102647:	f6 00 04             	testb  $0x4,(%eax)
f010264a:	74 24                	je     f0102670 <i386_vm_init+0xf52>
f010264c:	c7 44 24 0c fc 73 10 	movl   $0xf01073fc,0xc(%esp)
f0102653:	f0 
f0102654:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f010265b:	f0 
f010265c:	c7 44 24 04 7c 03 00 	movl   $0x37c,0x4(%esp)
f0102663:	00 
f0102664:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f010266b:	e8 15 da ff ff       	call   f0100085 <_panic>

	// should have pp1 at both 0 and PGSIZE, pp2 nowhere, ...
	assert(check_va2pa(boot_pgdir, 0) == page2pa(pp1));
f0102670:	ba 00 00 00 00       	mov    $0x0,%edx
f0102675:	a1 28 ff 2c f0       	mov    0xf02cff28,%eax
f010267a:	e8 e6 e9 ff ff       	call   f0101065 <check_va2pa>
f010267f:	8b 55 dc             	mov    -0x24(%ebp),%edx
f0102682:	2b 15 2c ff 2c f0    	sub    0xf02cff2c,%edx
f0102688:	c1 fa 02             	sar    $0x2,%edx
f010268b:	69 d2 ab aa aa aa    	imul   $0xaaaaaaab,%edx,%edx
f0102691:	c1 e2 0c             	shl    $0xc,%edx
f0102694:	39 d0                	cmp    %edx,%eax
f0102696:	74 24                	je     f01026bc <i386_vm_init+0xf9e>
f0102698:	c7 44 24 0c 34 74 10 	movl   $0xf0107434,0xc(%esp)
f010269f:	f0 
f01026a0:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f01026a7:	f0 
f01026a8:	c7 44 24 04 7f 03 00 	movl   $0x37f,0x4(%esp)
f01026af:	00 
f01026b0:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f01026b7:	e8 c9 d9 ff ff       	call   f0100085 <_panic>
	assert(check_va2pa(boot_pgdir, PGSIZE) == page2pa(pp1));
f01026bc:	ba 00 10 00 00       	mov    $0x1000,%edx
f01026c1:	a1 28 ff 2c f0       	mov    0xf02cff28,%eax
f01026c6:	e8 9a e9 ff ff       	call   f0101065 <check_va2pa>
f01026cb:	8b 55 dc             	mov    -0x24(%ebp),%edx
f01026ce:	89 d1                	mov    %edx,%ecx
f01026d0:	2b 0d 2c ff 2c f0    	sub    0xf02cff2c,%ecx
f01026d6:	c1 f9 02             	sar    $0x2,%ecx
f01026d9:	69 c9 ab aa aa aa    	imul   $0xaaaaaaab,%ecx,%ecx
f01026df:	c1 e1 0c             	shl    $0xc,%ecx
f01026e2:	39 c8                	cmp    %ecx,%eax
f01026e4:	74 24                	je     f010270a <i386_vm_init+0xfec>
f01026e6:	c7 44 24 0c 60 74 10 	movl   $0xf0107460,0xc(%esp)
f01026ed:	f0 
f01026ee:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f01026f5:	f0 
f01026f6:	c7 44 24 04 80 03 00 	movl   $0x380,0x4(%esp)
f01026fd:	00 
f01026fe:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0102705:	e8 7b d9 ff ff       	call   f0100085 <_panic>
	// ... and ref counts should reflect this
	assert(pp1->pp_ref == 2);
f010270a:	66 83 7a 08 02       	cmpw   $0x2,0x8(%edx)
f010270f:	74 24                	je     f0102735 <i386_vm_init+0x1017>
f0102711:	c7 44 24 0c e9 77 10 	movl   $0xf01077e9,0xc(%esp)
f0102718:	f0 
f0102719:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0102720:	f0 
f0102721:	c7 44 24 04 82 03 00 	movl   $0x382,0x4(%esp)
f0102728:	00 
f0102729:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0102730:	e8 50 d9 ff ff       	call   f0100085 <_panic>
	assert(pp2->pp_ref == 0);
f0102735:	8b 45 d8             	mov    -0x28(%ebp),%eax
f0102738:	66 83 78 08 00       	cmpw   $0x0,0x8(%eax)
f010273d:	74 24                	je     f0102763 <i386_vm_init+0x1045>
f010273f:	c7 44 24 0c fa 77 10 	movl   $0xf01077fa,0xc(%esp)
f0102746:	f0 
f0102747:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f010274e:	f0 
f010274f:	c7 44 24 04 83 03 00 	movl   $0x383,0x4(%esp)
f0102756:	00 
f0102757:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f010275e:	e8 22 d9 ff ff       	call   f0100085 <_panic>

	// pp2 should be returned by page_alloc
	assert(page_alloc(&pp) == 0 && pp == pp2);
f0102763:	8d 45 e4             	lea    -0x1c(%ebp),%eax
f0102766:	89 04 24             	mov    %eax,(%esp)
f0102769:	e8 5d e9 ff ff       	call   f01010cb <page_alloc>
f010276e:	85 c0                	test   %eax,%eax
f0102770:	75 08                	jne    f010277a <i386_vm_init+0x105c>
f0102772:	8b 45 e4             	mov    -0x1c(%ebp),%eax
f0102775:	3b 45 d8             	cmp    -0x28(%ebp),%eax
f0102778:	74 24                	je     f010279e <i386_vm_init+0x1080>
f010277a:	c7 44 24 0c 90 74 10 	movl   $0xf0107490,0xc(%esp)
f0102781:	f0 
f0102782:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0102789:	f0 
f010278a:	c7 44 24 04 86 03 00 	movl   $0x386,0x4(%esp)
f0102791:	00 
f0102792:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0102799:	e8 e7 d8 ff ff       	call   f0100085 <_panic>

	// unmapping pp1 at 0 should keep pp1 at PGSIZE
	page_remove(boot_pgdir, 0x0);
f010279e:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
f01027a5:	00 
f01027a6:	a1 28 ff 2c f0       	mov    0xf02cff28,%eax
f01027ab:	89 04 24             	mov    %eax,(%esp)
f01027ae:	e8 8c ec ff ff       	call   f010143f <page_remove>
	assert(check_va2pa(boot_pgdir, 0x0) == ~0);
f01027b3:	ba 00 00 00 00       	mov    $0x0,%edx
f01027b8:	a1 28 ff 2c f0       	mov    0xf02cff28,%eax
f01027bd:	e8 a3 e8 ff ff       	call   f0101065 <check_va2pa>
f01027c2:	83 f8 ff             	cmp    $0xffffffff,%eax
f01027c5:	74 24                	je     f01027eb <i386_vm_init+0x10cd>
f01027c7:	c7 44 24 0c b4 74 10 	movl   $0xf01074b4,0xc(%esp)
f01027ce:	f0 
f01027cf:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f01027d6:	f0 
f01027d7:	c7 44 24 04 8a 03 00 	movl   $0x38a,0x4(%esp)
f01027de:	00 
f01027df:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f01027e6:	e8 9a d8 ff ff       	call   f0100085 <_panic>
	assert(check_va2pa(boot_pgdir, PGSIZE) == page2pa(pp1));
f01027eb:	ba 00 10 00 00       	mov    $0x1000,%edx
f01027f0:	a1 28 ff 2c f0       	mov    0xf02cff28,%eax
f01027f5:	e8 6b e8 ff ff       	call   f0101065 <check_va2pa>
f01027fa:	8b 55 dc             	mov    -0x24(%ebp),%edx
f01027fd:	89 d1                	mov    %edx,%ecx
f01027ff:	2b 0d 2c ff 2c f0    	sub    0xf02cff2c,%ecx
f0102805:	c1 f9 02             	sar    $0x2,%ecx
f0102808:	69 c9 ab aa aa aa    	imul   $0xaaaaaaab,%ecx,%ecx
f010280e:	c1 e1 0c             	shl    $0xc,%ecx
f0102811:	39 c8                	cmp    %ecx,%eax
f0102813:	74 24                	je     f0102839 <i386_vm_init+0x111b>
f0102815:	c7 44 24 0c 60 74 10 	movl   $0xf0107460,0xc(%esp)
f010281c:	f0 
f010281d:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0102824:	f0 
f0102825:	c7 44 24 04 8b 03 00 	movl   $0x38b,0x4(%esp)
f010282c:	00 
f010282d:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0102834:	e8 4c d8 ff ff       	call   f0100085 <_panic>
	assert(pp1->pp_ref == 1);
f0102839:	66 83 7a 08 01       	cmpw   $0x1,0x8(%edx)
f010283e:	74 24                	je     f0102864 <i386_vm_init+0x1146>
f0102840:	c7 44 24 0c a0 77 10 	movl   $0xf01077a0,0xc(%esp)
f0102847:	f0 
f0102848:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f010284f:	f0 
f0102850:	c7 44 24 04 8c 03 00 	movl   $0x38c,0x4(%esp)
f0102857:	00 
f0102858:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f010285f:	e8 21 d8 ff ff       	call   f0100085 <_panic>
	assert(pp2->pp_ref == 0);
f0102864:	8b 45 d8             	mov    -0x28(%ebp),%eax
f0102867:	66 83 78 08 00       	cmpw   $0x0,0x8(%eax)
f010286c:	74 24                	je     f0102892 <i386_vm_init+0x1174>
f010286e:	c7 44 24 0c fa 77 10 	movl   $0xf01077fa,0xc(%esp)
f0102875:	f0 
f0102876:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f010287d:	f0 
f010287e:	c7 44 24 04 8d 03 00 	movl   $0x38d,0x4(%esp)
f0102885:	00 
f0102886:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f010288d:	e8 f3 d7 ff ff       	call   f0100085 <_panic>

	// unmapping pp1 at PGSIZE should free it
	page_remove(boot_pgdir, (void*) PGSIZE);
f0102892:	c7 44 24 04 00 10 00 	movl   $0x1000,0x4(%esp)
f0102899:	00 
f010289a:	a1 28 ff 2c f0       	mov    0xf02cff28,%eax
f010289f:	89 04 24             	mov    %eax,(%esp)
f01028a2:	e8 98 eb ff ff       	call   f010143f <page_remove>
	assert(check_va2pa(boot_pgdir, 0x0) == ~0);
f01028a7:	ba 00 00 00 00       	mov    $0x0,%edx
f01028ac:	a1 28 ff 2c f0       	mov    0xf02cff28,%eax
f01028b1:	e8 af e7 ff ff       	call   f0101065 <check_va2pa>
f01028b6:	83 f8 ff             	cmp    $0xffffffff,%eax
f01028b9:	74 24                	je     f01028df <i386_vm_init+0x11c1>
f01028bb:	c7 44 24 0c b4 74 10 	movl   $0xf01074b4,0xc(%esp)
f01028c2:	f0 
f01028c3:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f01028ca:	f0 
f01028cb:	c7 44 24 04 91 03 00 	movl   $0x391,0x4(%esp)
f01028d2:	00 
f01028d3:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f01028da:	e8 a6 d7 ff ff       	call   f0100085 <_panic>
	assert(check_va2pa(boot_pgdir, PGSIZE) == ~0);
f01028df:	ba 00 10 00 00       	mov    $0x1000,%edx
f01028e4:	a1 28 ff 2c f0       	mov    0xf02cff28,%eax
f01028e9:	e8 77 e7 ff ff       	call   f0101065 <check_va2pa>
f01028ee:	83 f8 ff             	cmp    $0xffffffff,%eax
f01028f1:	74 24                	je     f0102917 <i386_vm_init+0x11f9>
f01028f3:	c7 44 24 0c d8 74 10 	movl   $0xf01074d8,0xc(%esp)
f01028fa:	f0 
f01028fb:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0102902:	f0 
f0102903:	c7 44 24 04 92 03 00 	movl   $0x392,0x4(%esp)
f010290a:	00 
f010290b:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0102912:	e8 6e d7 ff ff       	call   f0100085 <_panic>
	assert(pp1->pp_ref == 0);
f0102917:	8b 45 dc             	mov    -0x24(%ebp),%eax
f010291a:	66 83 78 08 00       	cmpw   $0x0,0x8(%eax)
f010291f:	74 24                	je     f0102945 <i386_vm_init+0x1227>
f0102921:	c7 44 24 0c 0b 78 10 	movl   $0xf010780b,0xc(%esp)
f0102928:	f0 
f0102929:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0102930:	f0 
f0102931:	c7 44 24 04 93 03 00 	movl   $0x393,0x4(%esp)
f0102938:	00 
f0102939:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0102940:	e8 40 d7 ff ff       	call   f0100085 <_panic>
	assert(pp2->pp_ref == 0);
f0102945:	8b 45 d8             	mov    -0x28(%ebp),%eax
f0102948:	66 83 78 08 00       	cmpw   $0x0,0x8(%eax)
f010294d:	74 24                	je     f0102973 <i386_vm_init+0x1255>
f010294f:	c7 44 24 0c fa 77 10 	movl   $0xf01077fa,0xc(%esp)
f0102956:	f0 
f0102957:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f010295e:	f0 
f010295f:	c7 44 24 04 94 03 00 	movl   $0x394,0x4(%esp)
f0102966:	00 
f0102967:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f010296e:	e8 12 d7 ff ff       	call   f0100085 <_panic>

	// so it should be returned by page_alloc
	assert(page_alloc(&pp) == 0 && pp == pp1);
f0102973:	8d 45 e4             	lea    -0x1c(%ebp),%eax
f0102976:	89 04 24             	mov    %eax,(%esp)
f0102979:	e8 4d e7 ff ff       	call   f01010cb <page_alloc>
f010297e:	85 c0                	test   %eax,%eax
f0102980:	75 08                	jne    f010298a <i386_vm_init+0x126c>
f0102982:	8b 45 e4             	mov    -0x1c(%ebp),%eax
f0102985:	3b 45 dc             	cmp    -0x24(%ebp),%eax
f0102988:	74 24                	je     f01029ae <i386_vm_init+0x1290>
f010298a:	c7 44 24 0c 00 75 10 	movl   $0xf0107500,0xc(%esp)
f0102991:	f0 
f0102992:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0102999:	f0 
f010299a:	c7 44 24 04 97 03 00 	movl   $0x397,0x4(%esp)
f01029a1:	00 
f01029a2:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f01029a9:	e8 d7 d6 ff ff       	call   f0100085 <_panic>

	// should be no free memory
	assert(page_alloc(&pp) == -E_NO_MEM);
f01029ae:	8d 45 e4             	lea    -0x1c(%ebp),%eax
f01029b1:	89 04 24             	mov    %eax,(%esp)
f01029b4:	e8 12 e7 ff ff       	call   f01010cb <page_alloc>
f01029b9:	83 f8 fc             	cmp    $0xfffffffc,%eax
f01029bc:	74 24                	je     f01029e2 <i386_vm_init+0x12c4>
f01029be:	c7 44 24 0c 83 77 10 	movl   $0xf0107783,0xc(%esp)
f01029c5:	f0 
f01029c6:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f01029cd:	f0 
f01029ce:	c7 44 24 04 9a 03 00 	movl   $0x39a,0x4(%esp)
f01029d5:	00 
f01029d6:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f01029dd:	e8 a3 d6 ff ff       	call   f0100085 <_panic>
	page_remove(boot_pgdir, 0x0);
	assert(pp2->pp_ref == 0);
#endif

	// forcibly take pp0 back
	assert(PTE_ADDR(boot_pgdir[0]) == page2pa(pp0));
f01029e2:	a1 28 ff 2c f0       	mov    0xf02cff28,%eax
f01029e7:	8b 08                	mov    (%eax),%ecx
f01029e9:	81 e1 00 f0 ff ff    	and    $0xfffff000,%ecx
f01029ef:	8b 55 e0             	mov    -0x20(%ebp),%edx
f01029f2:	2b 15 2c ff 2c f0    	sub    0xf02cff2c,%edx
f01029f8:	c1 fa 02             	sar    $0x2,%edx
f01029fb:	69 d2 ab aa aa aa    	imul   $0xaaaaaaab,%edx,%edx
f0102a01:	c1 e2 0c             	shl    $0xc,%edx
f0102a04:	39 d1                	cmp    %edx,%ecx
f0102a06:	74 24                	je     f0102a2c <i386_vm_init+0x130e>
f0102a08:	c7 44 24 0c 20 72 10 	movl   $0xf0107220,0xc(%esp)
f0102a0f:	f0 
f0102a10:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0102a17:	f0 
f0102a18:	c7 44 24 04 ad 03 00 	movl   $0x3ad,0x4(%esp)
f0102a1f:	00 
f0102a20:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0102a27:	e8 59 d6 ff ff       	call   f0100085 <_panic>
	boot_pgdir[0] = 0;
f0102a2c:	c7 00 00 00 00 00    	movl   $0x0,(%eax)
	assert(pp0->pp_ref == 1);
f0102a32:	8b 45 e0             	mov    -0x20(%ebp),%eax
f0102a35:	66 83 78 08 01       	cmpw   $0x1,0x8(%eax)
f0102a3a:	74 24                	je     f0102a60 <i386_vm_init+0x1342>
f0102a3c:	c7 44 24 0c b1 77 10 	movl   $0xf01077b1,0xc(%esp)
f0102a43:	f0 
f0102a44:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0102a4b:	f0 
f0102a4c:	c7 44 24 04 af 03 00 	movl   $0x3af,0x4(%esp)
f0102a53:	00 
f0102a54:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0102a5b:	e8 25 d6 ff ff       	call   f0100085 <_panic>
	pp0->pp_ref = 0;
f0102a60:	66 c7 40 08 00 00    	movw   $0x0,0x8(%eax)
	
	// check pointer arithmetic in pgdir_walk
	page_free(pp0);
f0102a66:	8b 45 e0             	mov    -0x20(%ebp),%eax
f0102a69:	89 04 24             	mov    %eax,(%esp)
f0102a6c:	e8 0e e5 ff ff       	call   f0100f7f <page_free>
	va = (void*)(PGSIZE * NPDENTRIES + PGSIZE);
	ptep = pgdir_walk(boot_pgdir, va, 1);
f0102a71:	c7 44 24 08 01 00 00 	movl   $0x1,0x8(%esp)
f0102a78:	00 
f0102a79:	c7 44 24 04 00 10 40 	movl   $0x401000,0x4(%esp)
f0102a80:	00 
f0102a81:	a1 28 ff 2c f0       	mov    0xf02cff28,%eax
f0102a86:	89 04 24             	mov    %eax,(%esp)
f0102a89:	e8 8e e6 ff ff       	call   f010111c <pgdir_walk>
f0102a8e:	89 45 d4             	mov    %eax,-0x2c(%ebp)
	ptep1 = KADDR(PTE_ADDR(boot_pgdir[PDX(va)]));
f0102a91:	8b 0d 28 ff 2c f0    	mov    0xf02cff28,%ecx
f0102a97:	83 c1 04             	add    $0x4,%ecx
f0102a9a:	8b 11                	mov    (%ecx),%edx
f0102a9c:	81 e2 00 f0 ff ff    	and    $0xfffff000,%edx
f0102aa2:	89 d6                	mov    %edx,%esi
f0102aa4:	c1 ee 0c             	shr    $0xc,%esi
f0102aa7:	3b 35 20 ff 2c f0    	cmp    0xf02cff20,%esi
f0102aad:	72 20                	jb     f0102acf <i386_vm_init+0x13b1>
f0102aaf:	89 54 24 0c          	mov    %edx,0xc(%esp)
f0102ab3:	c7 44 24 08 50 70 10 	movl   $0xf0107050,0x8(%esp)
f0102aba:	f0 
f0102abb:	c7 44 24 04 b6 03 00 	movl   $0x3b6,0x4(%esp)
f0102ac2:	00 
f0102ac3:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0102aca:	e8 b6 d5 ff ff       	call   f0100085 <_panic>
	assert(ptep == ptep1 + PTX(va));
f0102acf:	81 ea fc ff ff 0f    	sub    $0xffffffc,%edx
f0102ad5:	39 d0                	cmp    %edx,%eax
f0102ad7:	74 24                	je     f0102afd <i386_vm_init+0x13df>
f0102ad9:	c7 44 24 0c 1c 78 10 	movl   $0xf010781c,0xc(%esp)
f0102ae0:	f0 
f0102ae1:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0102ae8:	f0 
f0102ae9:	c7 44 24 04 b7 03 00 	movl   $0x3b7,0x4(%esp)
f0102af0:	00 
f0102af1:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0102af8:	e8 88 d5 ff ff       	call   f0100085 <_panic>
	boot_pgdir[PDX(va)] = 0;
f0102afd:	c7 01 00 00 00 00    	movl   $0x0,(%ecx)
	pp0->pp_ref = 0;
f0102b03:	8b 45 e0             	mov    -0x20(%ebp),%eax
f0102b06:	66 c7 40 08 00 00    	movw   $0x0,0x8(%eax)
}

static inline physaddr_t
page2pa(struct Page *pp)
{
	return page2ppn(pp) << PGSHIFT;
f0102b0c:	8b 45 e0             	mov    -0x20(%ebp),%eax
f0102b0f:	2b 05 2c ff 2c f0    	sub    0xf02cff2c,%eax
f0102b15:	c1 f8 02             	sar    $0x2,%eax
f0102b18:	69 c0 ab aa aa aa    	imul   $0xaaaaaaab,%eax,%eax
f0102b1e:	c1 e0 0c             	shl    $0xc,%eax
}

static inline void*
page2kva(struct Page *pp)
{
	return KADDR(page2pa(pp));
f0102b21:	89 c2                	mov    %eax,%edx
f0102b23:	c1 ea 0c             	shr    $0xc,%edx
f0102b26:	3b 15 20 ff 2c f0    	cmp    0xf02cff20,%edx
f0102b2c:	72 20                	jb     f0102b4e <i386_vm_init+0x1430>
f0102b2e:	89 44 24 0c          	mov    %eax,0xc(%esp)
f0102b32:	c7 44 24 08 50 70 10 	movl   $0xf0107050,0x8(%esp)
f0102b39:	f0 
f0102b3a:	c7 44 24 04 5a 00 00 	movl   $0x5a,0x4(%esp)
f0102b41:	00 
f0102b42:	c7 04 24 7d 6c 10 f0 	movl   $0xf0106c7d,(%esp)
f0102b49:	e8 37 d5 ff ff       	call   f0100085 <_panic>
	
	// check that new page tables get cleared
	memset(page2kva(pp0), 0xFF, PGSIZE);
f0102b4e:	c7 44 24 08 00 10 00 	movl   $0x1000,0x8(%esp)
f0102b55:	00 
f0102b56:	c7 44 24 04 ff 00 00 	movl   $0xff,0x4(%esp)
f0102b5d:	00 
f0102b5e:	2d 00 00 00 10       	sub    $0x10000000,%eax
f0102b63:	89 04 24             	mov    %eax,(%esp)
f0102b66:	e8 3b 2f 00 00       	call   f0105aa6 <memset>
	page_free(pp0);
f0102b6b:	8b 45 e0             	mov    -0x20(%ebp),%eax
f0102b6e:	89 04 24             	mov    %eax,(%esp)
f0102b71:	e8 09 e4 ff ff       	call   f0100f7f <page_free>
	pgdir_walk(boot_pgdir, 0x0, 1);
f0102b76:	c7 44 24 08 01 00 00 	movl   $0x1,0x8(%esp)
f0102b7d:	00 
f0102b7e:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
f0102b85:	00 
f0102b86:	a1 28 ff 2c f0       	mov    0xf02cff28,%eax
f0102b8b:	89 04 24             	mov    %eax,(%esp)
f0102b8e:	e8 89 e5 ff ff       	call   f010111c <pgdir_walk>
}

static inline physaddr_t
page2pa(struct Page *pp)
{
	return page2ppn(pp) << PGSHIFT;
f0102b93:	8b 55 e0             	mov    -0x20(%ebp),%edx
f0102b96:	2b 15 2c ff 2c f0    	sub    0xf02cff2c,%edx
f0102b9c:	c1 fa 02             	sar    $0x2,%edx
f0102b9f:	69 d2 ab aa aa aa    	imul   $0xaaaaaaab,%edx,%edx
f0102ba5:	c1 e2 0c             	shl    $0xc,%edx
}

static inline void*
page2kva(struct Page *pp)
{
	return KADDR(page2pa(pp));
f0102ba8:	89 d0                	mov    %edx,%eax
f0102baa:	c1 e8 0c             	shr    $0xc,%eax
f0102bad:	3b 05 20 ff 2c f0    	cmp    0xf02cff20,%eax
f0102bb3:	72 20                	jb     f0102bd5 <i386_vm_init+0x14b7>
f0102bb5:	89 54 24 0c          	mov    %edx,0xc(%esp)
f0102bb9:	c7 44 24 08 50 70 10 	movl   $0xf0107050,0x8(%esp)
f0102bc0:	f0 
f0102bc1:	c7 44 24 04 5a 00 00 	movl   $0x5a,0x4(%esp)
f0102bc8:	00 
f0102bc9:	c7 04 24 7d 6c 10 f0 	movl   $0xf0106c7d,(%esp)
f0102bd0:	e8 b0 d4 ff ff       	call   f0100085 <_panic>
	ptep = page2kva(pp0);
f0102bd5:	8d 82 00 00 00 f0    	lea    -0x10000000(%edx),%eax
f0102bdb:	89 45 d4             	mov    %eax,-0x2c(%ebp)
	for(i=0; i<NPTENTRIES; i++)
		assert((ptep[i] & PTE_P) == 0);
f0102bde:	f6 00 01             	testb  $0x1,(%eax)
f0102be1:	75 11                	jne    f0102bf4 <i386_vm_init+0x14d6>
f0102be3:	8d 82 04 00 00 f0    	lea    -0xffffffc(%edx),%eax
//
// From UTOP to ULIM, the user is allowed to read but not write.
// Above ULIM the user cannot read (or write). 

void
i386_vm_init(void)
f0102be9:	81 ea 00 f0 ff 0f    	sub    $0xffff000,%edx
	memset(page2kva(pp0), 0xFF, PGSIZE);
	page_free(pp0);
	pgdir_walk(boot_pgdir, 0x0, 1);
	ptep = page2kva(pp0);
	for(i=0; i<NPTENTRIES; i++)
		assert((ptep[i] & PTE_P) == 0);
f0102bef:	f6 00 01             	testb  $0x1,(%eax)
f0102bf2:	74 24                	je     f0102c18 <i386_vm_init+0x14fa>
f0102bf4:	c7 44 24 0c 34 78 10 	movl   $0xf0107834,0xc(%esp)
f0102bfb:	f0 
f0102bfc:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0102c03:	f0 
f0102c04:	c7 44 24 04 c1 03 00 	movl   $0x3c1,0x4(%esp)
f0102c0b:	00 
f0102c0c:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0102c13:	e8 6d d4 ff ff       	call   f0100085 <_panic>
f0102c18:	83 c0 04             	add    $0x4,%eax
	// check that new page tables get cleared
	memset(page2kva(pp0), 0xFF, PGSIZE);
	page_free(pp0);
	pgdir_walk(boot_pgdir, 0x0, 1);
	ptep = page2kva(pp0);
	for(i=0; i<NPTENTRIES; i++)
f0102c1b:	39 d0                	cmp    %edx,%eax
f0102c1d:	75 d0                	jne    f0102bef <i386_vm_init+0x14d1>
		assert((ptep[i] & PTE_P) == 0);
	boot_pgdir[0] = 0;
f0102c1f:	a1 28 ff 2c f0       	mov    0xf02cff28,%eax
f0102c24:	c7 00 00 00 00 00    	movl   $0x0,(%eax)
	pp0->pp_ref = 0;
f0102c2a:	8b 45 e0             	mov    -0x20(%ebp),%eax
f0102c2d:	66 c7 40 08 00 00    	movw   $0x0,0x8(%eax)

	// give free list back
	page_free_list = fl;
f0102c33:	89 1d 1c ff 2c f0    	mov    %ebx,0xf02cff1c

	// free the pages we took
	page_free(pp0);
f0102c39:	8b 45 e0             	mov    -0x20(%ebp),%eax
f0102c3c:	89 04 24             	mov    %eax,(%esp)
f0102c3f:	e8 3b e3 ff ff       	call   f0100f7f <page_free>
	page_free(pp1);
f0102c44:	8b 45 dc             	mov    -0x24(%ebp),%eax
f0102c47:	89 04 24             	mov    %eax,(%esp)
f0102c4a:	e8 30 e3 ff ff       	call   f0100f7f <page_free>
	page_free(pp2);
f0102c4f:	8b 45 d8             	mov    -0x28(%ebp),%eax
f0102c52:	89 04 24             	mov    %eax,(%esp)
f0102c55:	e8 25 e3 ff ff       	call   f0100f7f <page_free>
	
	cprintf("page_check() succeeded!\n");
f0102c5a:	c7 04 24 4b 78 10 f0 	movl   $0xf010784b,(%esp)
f0102c61:	e8 79 0d 00 00       	call   f01039df <cprintf>
	// Permissions:
	//    - the new image at UPAGES -- kernel R, user R
	//      (ie. perm = PTE_U | PTE_P)
	//    - pages itself -- kernel RW, user NONE
	// Your code goes here:
    n   = ROUNDUP(npage*sizeof(struct Page), PGSIZE);
f0102c66:	8b 15 20 ff 2c f0    	mov    0xf02cff20,%edx
    boot_map_segment(boot_pgdir, UPAGES, n, PADDR(pages), PTE_U|PTE_P);
f0102c6c:	a1 2c ff 2c f0       	mov    0xf02cff2c,%eax
f0102c71:	3d ff ff ff ef       	cmp    $0xefffffff,%eax
f0102c76:	77 20                	ja     f0102c98 <i386_vm_init+0x157a>
f0102c78:	89 44 24 0c          	mov    %eax,0xc(%esp)
f0102c7c:	c7 44 24 08 d0 70 10 	movl   $0xf01070d0,0x8(%esp)
f0102c83:	f0 
f0102c84:	c7 44 24 04 e0 00 00 	movl   $0xe0,0x4(%esp)
f0102c8b:	00 
f0102c8c:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0102c93:	e8 ed d3 ff ff       	call   f0100085 <_panic>
	// Permissions:
	//    - the new image at UPAGES -- kernel R, user R
	//      (ie. perm = PTE_U | PTE_P)
	//    - pages itself -- kernel RW, user NONE
	// Your code goes here:
    n   = ROUNDUP(npage*sizeof(struct Page), PGSIZE);
f0102c98:	8d 14 52             	lea    (%edx,%edx,2),%edx
f0102c9b:	8d 0c 95 ff 0f 00 00 	lea    0xfff(,%edx,4),%ecx
    boot_map_segment(boot_pgdir, UPAGES, n, PADDR(pages), PTE_U|PTE_P);
f0102ca2:	81 e1 00 f0 ff ff    	and    $0xfffff000,%ecx
f0102ca8:	c7 44 24 04 05 00 00 	movl   $0x5,0x4(%esp)
f0102caf:	00 
f0102cb0:	05 00 00 00 10       	add    $0x10000000,%eax
f0102cb5:	89 04 24             	mov    %eax,(%esp)
f0102cb8:	ba 00 00 00 ef       	mov    $0xef000000,%edx
f0102cbd:	a1 28 ff 2c f0       	mov    0xf02cff28,%eax
f0102cc2:	e8 c5 e8 ff ff       	call   f010158c <boot_map_segment>
	// Permissions:
	//    - the new image at UENVS  -- kernel R, user R
	//    - envs itself -- kernel RW, user NONE
	// LAB 3: Your code here.
    n   = ROUNDUP(NENV*sizeof(struct Env), PGSIZE);
    boot_map_segment(boot_pgdir, UENVS, n, PADDR(envs), PTE_U|PTE_P);
f0102cc7:	a1 5c f2 2c f0       	mov    0xf02cf25c,%eax
f0102ccc:	3d ff ff ff ef       	cmp    $0xefffffff,%eax
f0102cd1:	77 20                	ja     f0102cf3 <i386_vm_init+0x15d5>
f0102cd3:	89 44 24 0c          	mov    %eax,0xc(%esp)
f0102cd7:	c7 44 24 08 d0 70 10 	movl   $0xf01070d0,0x8(%esp)
f0102cde:	f0 
f0102cdf:	c7 44 24 04 ea 00 00 	movl   $0xea,0x4(%esp)
f0102ce6:	00 
f0102ce7:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0102cee:	e8 92 d3 ff ff       	call   f0100085 <_panic>
f0102cf3:	c7 44 24 04 05 00 00 	movl   $0x5,0x4(%esp)
f0102cfa:	00 
f0102cfb:	05 00 00 00 10       	add    $0x10000000,%eax
f0102d00:	89 04 24             	mov    %eax,(%esp)
f0102d03:	b9 00 f0 01 00       	mov    $0x1f000,%ecx
f0102d08:	ba 00 00 c0 ee       	mov    $0xeec00000,%edx
f0102d0d:	a1 28 ff 2c f0       	mov    0xf02cff28,%eax
f0102d12:	e8 75 e8 ff ff       	call   f010158c <boot_map_segment>
	//     * [KSTACKTOP-PTSIZE, KSTACKTOP-KSTKSIZE) -- not backed; so if
	//       the kernel overflows its stack, it will fault rather than
	//       overwrite memory.  Known as a "guard page".
	//     Permissions: kernel RW, user NONE
	// Your code goes here:
    boot_map_segment(boot_pgdir, KSTACKTOP-KSTKSIZE, KSTKSIZE, PADDR(bootstack), PTE_W|PTE_P);
f0102d17:	bb 00 60 11 f0       	mov    $0xf0116000,%ebx
f0102d1c:	81 fb ff ff ff ef    	cmp    $0xefffffff,%ebx
f0102d22:	77 20                	ja     f0102d44 <i386_vm_init+0x1626>
f0102d24:	89 5c 24 0c          	mov    %ebx,0xc(%esp)
f0102d28:	c7 44 24 08 d0 70 10 	movl   $0xf01070d0,0x8(%esp)
f0102d2f:	f0 
f0102d30:	c7 44 24 04 f7 00 00 	movl   $0xf7,0x4(%esp)
f0102d37:	00 
f0102d38:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0102d3f:	e8 41 d3 ff ff       	call   f0100085 <_panic>
f0102d44:	c7 44 24 04 03 00 00 	movl   $0x3,0x4(%esp)
f0102d4b:	00 
f0102d4c:	8d 83 00 00 00 10    	lea    0x10000000(%ebx),%eax
f0102d52:	89 04 24             	mov    %eax,(%esp)
f0102d55:	b9 00 80 00 00       	mov    $0x8000,%ecx
f0102d5a:	ba 00 80 bf ef       	mov    $0xefbf8000,%edx
f0102d5f:	a1 28 ff 2c f0       	mov    0xf02cff28,%eax
f0102d64:	e8 23 e8 ff ff       	call   f010158c <boot_map_segment>
	//      the PA range [0, 2^32 - KERNBASE)
	// We might not have 2^32 - KERNBASE bytes of physical memory, but
	// we just set up the mapping anyway.
	// Permissions: kernel RW, user NONE
	// Your code goes here: 
    boot_map_segment(boot_pgdir, KERNBASE, 0x0FFFFFFF, 0, PTE_W|PTE_P);
f0102d69:	c7 44 24 04 03 00 00 	movl   $0x3,0x4(%esp)
f0102d70:	00 
f0102d71:	c7 04 24 00 00 00 00 	movl   $0x0,(%esp)
f0102d78:	b9 ff ff ff 0f       	mov    $0xfffffff,%ecx
f0102d7d:	ba 00 00 00 f0       	mov    $0xf0000000,%edx
f0102d82:	a1 28 ff 2c f0       	mov    0xf02cff28,%eax
f0102d87:	e8 00 e8 ff ff       	call   f010158c <boot_map_segment>

	// Check that the initial page directory has been set up correctly.
	check_boot_pgdir(boot_pgdir);
f0102d8c:	8b 35 28 ff 2c f0    	mov    0xf02cff28,%esi
	//pde_t *pgdir;

	//pgdir = boot_pgdir;

	// check pages array
	n = ROUNDUP(npage*sizeof(struct Page), PGSIZE);
f0102d92:	6b 05 20 ff 2c f0 0c 	imul   $0xc,0xf02cff20,%eax
f0102d99:	05 ff 0f 00 00       	add    $0xfff,%eax
f0102d9e:	25 00 f0 ff ff       	and    $0xfffff000,%eax
f0102da3:	89 45 c4             	mov    %eax,-0x3c(%ebp)
f0102da6:	bf 00 00 00 00       	mov    $0x0,%edi
f0102dab:	eb 70                	jmp    f0102e1d <i386_vm_init+0x16ff>
	for (i = 0; i < n; i += PGSIZE)
		assert(check_va2pa(pgdir, UPAGES + i) == PADDR(pages) + i);
f0102dad:	8d 97 00 00 00 ef    	lea    -0x11000000(%edi),%edx
f0102db3:	89 f0                	mov    %esi,%eax
f0102db5:	e8 ab e2 ff ff       	call   f0101065 <check_va2pa>
f0102dba:	8b 15 2c ff 2c f0    	mov    0xf02cff2c,%edx
f0102dc0:	81 fa ff ff ff ef    	cmp    $0xefffffff,%edx
f0102dc6:	77 20                	ja     f0102de8 <i386_vm_init+0x16ca>
f0102dc8:	89 54 24 0c          	mov    %edx,0xc(%esp)
f0102dcc:	c7 44 24 08 d0 70 10 	movl   $0xf01070d0,0x8(%esp)
f0102dd3:	f0 
f0102dd4:	c7 44 24 04 96 01 00 	movl   $0x196,0x4(%esp)
f0102ddb:	00 
f0102ddc:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0102de3:	e8 9d d2 ff ff       	call   f0100085 <_panic>
f0102de8:	8d 94 17 00 00 00 10 	lea    0x10000000(%edi,%edx,1),%edx
f0102def:	39 d0                	cmp    %edx,%eax
f0102df1:	74 24                	je     f0102e17 <i386_vm_init+0x16f9>
f0102df3:	c7 44 24 0c 24 75 10 	movl   $0xf0107524,0xc(%esp)
f0102dfa:	f0 
f0102dfb:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0102e02:	f0 
f0102e03:	c7 44 24 04 96 01 00 	movl   $0x196,0x4(%esp)
f0102e0a:	00 
f0102e0b:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0102e12:	e8 6e d2 ff ff       	call   f0100085 <_panic>

	//pgdir = boot_pgdir;

	// check pages array
	n = ROUNDUP(npage*sizeof(struct Page), PGSIZE);
	for (i = 0; i < n; i += PGSIZE)
f0102e17:	81 c7 00 10 00 00    	add    $0x1000,%edi
f0102e1d:	39 7d c4             	cmp    %edi,-0x3c(%ebp)
f0102e20:	77 8b                	ja     f0102dad <i386_vm_init+0x168f>
f0102e22:	bf 00 00 00 00       	mov    $0x0,%edi
		assert(check_va2pa(pgdir, UPAGES + i) == PADDR(pages) + i);
	
	// check envs array (new test for lab 3)
	n = ROUNDUP(NENV*sizeof(struct Env), PGSIZE);
	for (i = 0; i < n; i += PGSIZE)
		assert(check_va2pa(pgdir, UENVS + i) == PADDR(envs) + i);
f0102e27:	8d 97 00 00 c0 ee    	lea    -0x11400000(%edi),%edx
f0102e2d:	89 f0                	mov    %esi,%eax
f0102e2f:	e8 31 e2 ff ff       	call   f0101065 <check_va2pa>
f0102e34:	8b 15 5c f2 2c f0    	mov    0xf02cf25c,%edx
f0102e3a:	81 fa ff ff ff ef    	cmp    $0xefffffff,%edx
f0102e40:	77 20                	ja     f0102e62 <i386_vm_init+0x1744>
f0102e42:	89 54 24 0c          	mov    %edx,0xc(%esp)
f0102e46:	c7 44 24 08 d0 70 10 	movl   $0xf01070d0,0x8(%esp)
f0102e4d:	f0 
f0102e4e:	c7 44 24 04 9b 01 00 	movl   $0x19b,0x4(%esp)
f0102e55:	00 
f0102e56:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0102e5d:	e8 23 d2 ff ff       	call   f0100085 <_panic>
f0102e62:	8d 94 17 00 00 00 10 	lea    0x10000000(%edi,%edx,1),%edx
f0102e69:	39 d0                	cmp    %edx,%eax
f0102e6b:	74 24                	je     f0102e91 <i386_vm_init+0x1773>
f0102e6d:	c7 44 24 0c 58 75 10 	movl   $0xf0107558,0xc(%esp)
f0102e74:	f0 
f0102e75:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0102e7c:	f0 
f0102e7d:	c7 44 24 04 9b 01 00 	movl   $0x19b,0x4(%esp)
f0102e84:	00 
f0102e85:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0102e8c:	e8 f4 d1 ff ff       	call   f0100085 <_panic>
	for (i = 0; i < n; i += PGSIZE)
		assert(check_va2pa(pgdir, UPAGES + i) == PADDR(pages) + i);
	
	// check envs array (new test for lab 3)
	n = ROUNDUP(NENV*sizeof(struct Env), PGSIZE);
	for (i = 0; i < n; i += PGSIZE)
f0102e91:	81 c7 00 10 00 00    	add    $0x1000,%edi
f0102e97:	81 ff 00 f0 01 00    	cmp    $0x1f000,%edi
f0102e9d:	75 88                	jne    f0102e27 <i386_vm_init+0x1709>
f0102e9f:	bf 00 00 00 00       	mov    $0x0,%edi
f0102ea4:	eb 3b                	jmp    f0102ee1 <i386_vm_init+0x17c3>
		assert(check_va2pa(pgdir, UENVS + i) == PADDR(envs) + i);

	// check phys mem
	for (i = 0; i < npage * PGSIZE; i += PGSIZE)
		assert(check_va2pa(pgdir, KERNBASE + i) == i);
f0102ea6:	8d 97 00 00 00 f0    	lea    -0x10000000(%edi),%edx
f0102eac:	89 f0                	mov    %esi,%eax
f0102eae:	e8 b2 e1 ff ff       	call   f0101065 <check_va2pa>
f0102eb3:	39 c7                	cmp    %eax,%edi
f0102eb5:	74 24                	je     f0102edb <i386_vm_init+0x17bd>
f0102eb7:	c7 44 24 0c 8c 75 10 	movl   $0xf010758c,0xc(%esp)
f0102ebe:	f0 
f0102ebf:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0102ec6:	f0 
f0102ec7:	c7 44 24 04 9f 01 00 	movl   $0x19f,0x4(%esp)
f0102ece:	00 
f0102ecf:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0102ed6:	e8 aa d1 ff ff       	call   f0100085 <_panic>
	n = ROUNDUP(NENV*sizeof(struct Env), PGSIZE);
	for (i = 0; i < n; i += PGSIZE)
		assert(check_va2pa(pgdir, UENVS + i) == PADDR(envs) + i);

	// check phys mem
	for (i = 0; i < npage * PGSIZE; i += PGSIZE)
f0102edb:	81 c7 00 10 00 00    	add    $0x1000,%edi
f0102ee1:	a1 20 ff 2c f0       	mov    0xf02cff20,%eax
f0102ee6:	c1 e0 0c             	shl    $0xc,%eax
f0102ee9:	39 c7                	cmp    %eax,%edi
f0102eeb:	72 b9                	jb     f0102ea6 <i386_vm_init+0x1788>
f0102eed:	bf 00 80 bf ef       	mov    $0xefbf8000,%edi
		assert(check_va2pa(pgdir, KERNBASE + i) == i);

	// check kernel stack
	for (i = 0; i < KSTKSIZE; i += PGSIZE)
		assert(check_va2pa(pgdir, KSTACKTOP - KSTKSIZE + i) == PADDR(bootstack) + i);
f0102ef2:	81 c3 00 80 40 20    	add    $0x20408000,%ebx
f0102ef8:	89 fa                	mov    %edi,%edx
f0102efa:	89 f0                	mov    %esi,%eax
f0102efc:	e8 64 e1 ff ff       	call   f0101065 <check_va2pa>
f0102f01:	8d 14 3b             	lea    (%ebx,%edi,1),%edx
f0102f04:	39 d0                	cmp    %edx,%eax
f0102f06:	74 24                	je     f0102f2c <i386_vm_init+0x180e>
f0102f08:	c7 44 24 0c b4 75 10 	movl   $0xf01075b4,0xc(%esp)
f0102f0f:	f0 
f0102f10:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0102f17:	f0 
f0102f18:	c7 44 24 04 a3 01 00 	movl   $0x1a3,0x4(%esp)
f0102f1f:	00 
f0102f20:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0102f27:	e8 59 d1 ff ff       	call   f0100085 <_panic>
f0102f2c:	81 c7 00 10 00 00    	add    $0x1000,%edi
	// check phys mem
	for (i = 0; i < npage * PGSIZE; i += PGSIZE)
		assert(check_va2pa(pgdir, KERNBASE + i) == i);

	// check kernel stack
	for (i = 0; i < KSTKSIZE; i += PGSIZE)
f0102f32:	81 ff 00 00 c0 ef    	cmp    $0xefc00000,%edi
f0102f38:	75 be                	jne    f0102ef8 <i386_vm_init+0x17da>
		assert(check_va2pa(pgdir, KSTACKTOP - KSTKSIZE + i) == PADDR(bootstack) + i);
	assert(check_va2pa(pgdir, KSTACKTOP - PTSIZE) == ~0);
f0102f3a:	ba 00 00 80 ef       	mov    $0xef800000,%edx
f0102f3f:	89 f0                	mov    %esi,%eax
f0102f41:	e8 1f e1 ff ff       	call   f0101065 <check_va2pa>
f0102f46:	ba 00 00 00 00       	mov    $0x0,%edx
f0102f4b:	83 f8 ff             	cmp    $0xffffffff,%eax
f0102f4e:	74 24                	je     f0102f74 <i386_vm_init+0x1856>
f0102f50:	c7 44 24 0c fc 75 10 	movl   $0xf01075fc,0xc(%esp)
f0102f57:	f0 
f0102f58:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0102f5f:	f0 
f0102f60:	c7 44 24 04 a4 01 00 	movl   $0x1a4,0x4(%esp)
f0102f67:	00 
f0102f68:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0102f6f:	e8 11 d1 ff ff       	call   f0100085 <_panic>

	// check for zero/non-zero in PDEs
	for (i = 0; i < NPDENTRIES; i++) {
		switch (i) {
f0102f74:	8d 82 45 fc ff ff    	lea    -0x3bb(%edx),%eax
f0102f7a:	83 f8 04             	cmp    $0x4,%eax
f0102f7d:	77 2e                	ja     f0102fad <i386_vm_init+0x188f>
		case PDX(VPT):
		case PDX(UVPT):
		case PDX(KSTACKTOP-1):
		case PDX(UPAGES):
		case PDX(UENVS):
			assert(pgdir[i]);
f0102f7f:	83 3c 96 00          	cmpl   $0x0,(%esi,%edx,4)
f0102f83:	0f 85 80 00 00 00    	jne    f0103009 <i386_vm_init+0x18eb>
f0102f89:	c7 44 24 0c 64 78 10 	movl   $0xf0107864,0xc(%esp)
f0102f90:	f0 
f0102f91:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0102f98:	f0 
f0102f99:	c7 44 24 04 ae 01 00 	movl   $0x1ae,0x4(%esp)
f0102fa0:	00 
f0102fa1:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0102fa8:	e8 d8 d0 ff ff       	call   f0100085 <_panic>
			break;
		default:
			if (i >= PDX(KERNBASE))
f0102fad:	81 fa bf 03 00 00    	cmp    $0x3bf,%edx
f0102fb3:	76 2a                	jbe    f0102fdf <i386_vm_init+0x18c1>
				assert(pgdir[i]);
f0102fb5:	83 3c 96 00          	cmpl   $0x0,(%esi,%edx,4)
f0102fb9:	75 4e                	jne    f0103009 <i386_vm_init+0x18eb>
f0102fbb:	c7 44 24 0c 64 78 10 	movl   $0xf0107864,0xc(%esp)
f0102fc2:	f0 
f0102fc3:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0102fca:	f0 
f0102fcb:	c7 44 24 04 b2 01 00 	movl   $0x1b2,0x4(%esp)
f0102fd2:	00 
f0102fd3:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0102fda:	e8 a6 d0 ff ff       	call   f0100085 <_panic>
			else
				assert(pgdir[i] == 0);
f0102fdf:	83 3c 96 00          	cmpl   $0x0,(%esi,%edx,4)
f0102fe3:	74 24                	je     f0103009 <i386_vm_init+0x18eb>
f0102fe5:	c7 44 24 0c 6d 78 10 	movl   $0xf010786d,0xc(%esp)
f0102fec:	f0 
f0102fed:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0102ff4:	f0 
f0102ff5:	c7 44 24 04 b4 01 00 	movl   $0x1b4,0x4(%esp)
f0102ffc:	00 
f0102ffd:	c7 04 24 4b 76 10 f0 	movl   $0xf010764b,(%esp)
f0103004:	e8 7c d0 ff ff       	call   f0100085 <_panic>
	for (i = 0; i < KSTKSIZE; i += PGSIZE)
		assert(check_va2pa(pgdir, KSTACKTOP - KSTKSIZE + i) == PADDR(bootstack) + i);
	assert(check_va2pa(pgdir, KSTACKTOP - PTSIZE) == ~0);

	// check for zero/non-zero in PDEs
	for (i = 0; i < NPDENTRIES; i++) {
f0103009:	83 c2 01             	add    $0x1,%edx
f010300c:	81 fa 00 04 00 00    	cmp    $0x400,%edx
f0103012:	0f 85 5c ff ff ff    	jne    f0102f74 <i386_vm_init+0x1856>
			else
				assert(pgdir[i] == 0);
			break;
		}
	}
	cprintf("check_boot_pgdir() succeeded!\n");
f0103018:	c7 04 24 2c 76 10 f0 	movl   $0xf010762c,(%esp)
f010301f:	e8 bb 09 00 00       	call   f01039df <cprintf>
	// mapping, even though we are turning on paging and reconfiguring
	// segmentation.

	// Map VA 0:4MB same as VA KERNBASE, i.e. to PA 0:4MB.
	// (Limits our kernel to <4MB)
	pgdir[0] = pgdir[PDX(KERNBASE)];
f0103024:	8b 55 bc             	mov    -0x44(%ebp),%edx
f0103027:	8b 82 00 0f 00 00    	mov    0xf00(%edx),%eax
f010302d:	89 02                	mov    %eax,(%edx)
}

static __inline void
lcr3(uint32_t val)
{
	__asm __volatile("movl %0,%%cr3" : : "r" (val));
f010302f:	a1 24 ff 2c f0       	mov    0xf02cff24,%eax
f0103034:	0f 22 d8             	mov    %eax,%cr3

static __inline uint32_t
rcr0(void)
{
	uint32_t val;
	__asm __volatile("movl %%cr0,%0" : "=r" (val));
f0103037:	0f 20 c0             	mov    %cr0,%eax
	// Install page table.
	lcr3(boot_cr3);

	// Turn on paging.
	cr0 = rcr0();
	cr0 |= CR0_PE|CR0_PG|CR0_AM|CR0_WP|CR0_NE|CR0_TS|CR0_EM|CR0_MP;
f010303a:	0d 2f 00 05 80       	or     $0x8005002f,%eax
}

static __inline void
lcr0(uint32_t val)
{
	__asm __volatile("movl %0,%%cr0" : : "r" (val));
f010303f:	83 e0 f3             	and    $0xfffffff3,%eax
f0103042:	0f 22 c0             	mov    %eax,%cr0

	// Current mapping: KERNBASE+x => x => x.
	// (x < 4MB so uses paging pgdir[0])

	// Reload all segment registers.
	asm volatile("lgdt gdt_pd");
f0103045:	0f 01 15 b0 e3 11 f0 	lgdtl  0xf011e3b0
	asm volatile("movw %%ax,%%gs" :: "a" (GD_UD|3));
f010304c:	b8 23 00 00 00       	mov    $0x23,%eax
f0103051:	8e e8                	mov    %eax,%gs
	asm volatile("movw %%ax,%%fs" :: "a" (GD_UD|3));
f0103053:	8e e0                	mov    %eax,%fs
	asm volatile("movw %%ax,%%es" :: "a" (GD_KD));
f0103055:	b0 10                	mov    $0x10,%al
f0103057:	8e c0                	mov    %eax,%es
	asm volatile("movw %%ax,%%ds" :: "a" (GD_KD));
f0103059:	8e d8                	mov    %eax,%ds
	asm volatile("movw %%ax,%%ss" :: "a" (GD_KD));
f010305b:	8e d0                	mov    %eax,%ss
	asm volatile("ljmp %0,$1f\n 1:\n" :: "i" (GD_KT));  // reload cs
f010305d:	ea 64 30 10 f0 08 00 	ljmp   $0x8,$0xf0103064
	asm volatile("lldt %%ax" :: "a" (0));
f0103064:	b0 00                	mov    $0x0,%al
f0103066:	0f 00 d0             	lldt   %ax

	// Final mapping: KERNBASE+x => KERNBASE+x => x.

	// This mapping was only used after paging was turned on but
	// before the segment registers were reloaded.
	pgdir[0] = 0;
f0103069:	c7 02 00 00 00 00    	movl   $0x0,(%edx)
}

static __inline void
lcr3(uint32_t val)
{
	__asm __volatile("movl %0,%%cr3" : : "r" (val));
f010306f:	a1 24 ff 2c f0       	mov    0xf02cff24,%eax
f0103074:	0f 22 d8             	mov    %eax,%cr3

	// Flush the TLB for good measure, to kill the pgdir[0] mapping.
	lcr3(boot_cr3);
}
f0103077:	83 c4 4c             	add    $0x4c,%esp
f010307a:	5b                   	pop    %ebx
f010307b:	5e                   	pop    %esi
f010307c:	5f                   	pop    %edi
f010307d:	5d                   	pop    %ebp
f010307e:	c3                   	ret    
	...

f0103080 <envid2env>:
//   On success, sets *env_store to the environment.
//   On error, sets *env_store to NULL.
//
int
envid2env(envid_t envid, struct Env **env_store, bool checkperm)
{
f0103080:	55                   	push   %ebp
f0103081:	89 e5                	mov    %esp,%ebp
f0103083:	53                   	push   %ebx
f0103084:	8b 45 08             	mov    0x8(%ebp),%eax
f0103087:	8b 4d 0c             	mov    0xc(%ebp),%ecx
	struct Env *e;

	// If envid is zero, return the current environment.
	if (envid == 0) {
f010308a:	85 c0                	test   %eax,%eax
f010308c:	75 0e                	jne    f010309c <envid2env+0x1c>
		*env_store = curenv;
f010308e:	a1 60 f2 2c f0       	mov    0xf02cf260,%eax
f0103093:	89 01                	mov    %eax,(%ecx)
f0103095:	b8 00 00 00 00       	mov    $0x0,%eax
		return 0;
f010309a:	eb 54                	jmp    f01030f0 <envid2env+0x70>
	// Look up the Env structure via the index part of the envid,
	// then check the env_id field in that struct Env
	// to ensure that the envid is not stale
	// (i.e., does not refer to a _previous_ environment
	// that used the same slot in the envs[] array).
	e = &envs[ENVX(envid)];
f010309c:	89 c2                	mov    %eax,%edx
f010309e:	81 e2 ff 03 00 00    	and    $0x3ff,%edx
f01030a4:	6b d2 7c             	imul   $0x7c,%edx,%edx
f01030a7:	03 15 5c f2 2c f0    	add    0xf02cf25c,%edx
	if (e->env_status == ENV_FREE || e->env_id != envid) {
f01030ad:	83 7a 54 00          	cmpl   $0x0,0x54(%edx)
f01030b1:	74 05                	je     f01030b8 <envid2env+0x38>
f01030b3:	39 42 4c             	cmp    %eax,0x4c(%edx)
f01030b6:	74 0d                	je     f01030c5 <envid2env+0x45>
		*env_store = 0;
f01030b8:	c7 01 00 00 00 00    	movl   $0x0,(%ecx)
f01030be:	b8 fe ff ff ff       	mov    $0xfffffffe,%eax
		return -E_BAD_ENV;
f01030c3:	eb 2b                	jmp    f01030f0 <envid2env+0x70>
	// Check that the calling environment has legitimate permission
	// to manipulate the specified environment.
	// If checkperm is set, the specified environment
	// must be either the current environment
	// or an immediate child of the current environment.
	if (checkperm && e != curenv && e->env_parent_id != curenv->env_id) {
f01030c5:	83 7d 10 00          	cmpl   $0x0,0x10(%ebp)
f01030c9:	74 1e                	je     f01030e9 <envid2env+0x69>
f01030cb:	a1 60 f2 2c f0       	mov    0xf02cf260,%eax
f01030d0:	39 c2                	cmp    %eax,%edx
f01030d2:	74 15                	je     f01030e9 <envid2env+0x69>
f01030d4:	8b 5a 50             	mov    0x50(%edx),%ebx
f01030d7:	3b 58 4c             	cmp    0x4c(%eax),%ebx
f01030da:	74 0d                	je     f01030e9 <envid2env+0x69>
		*env_store = 0;
f01030dc:	c7 01 00 00 00 00    	movl   $0x0,(%ecx)
f01030e2:	b8 fe ff ff ff       	mov    $0xfffffffe,%eax
		return -E_BAD_ENV;
f01030e7:	eb 07                	jmp    f01030f0 <envid2env+0x70>
	}

	*env_store = e;
f01030e9:	89 11                	mov    %edx,(%ecx)
f01030eb:	b8 00 00 00 00       	mov    $0x0,%eax
	return 0;
}
f01030f0:	5b                   	pop    %ebx
f01030f1:	5d                   	pop    %ebp
f01030f2:	c3                   	ret    

f01030f3 <env_pop_tf>:
//
// This function does not return.
//
void
env_pop_tf(struct Trapframe *tf)
{
f01030f3:	55                   	push   %ebp
f01030f4:	89 e5                	mov    %esp,%ebp
f01030f6:	83 ec 18             	sub    $0x18,%esp
	__asm __volatile("movl %0,%%esp\n"
f01030f9:	8b 65 08             	mov    0x8(%ebp),%esp
f01030fc:	61                   	popa   
f01030fd:	07                   	pop    %es
f01030fe:	1f                   	pop    %ds
f01030ff:	83 c4 08             	add    $0x8,%esp
f0103102:	cf                   	iret   
		"\tpopl %%es\n"
		"\tpopl %%ds\n"
		"\taddl $0x8,%%esp\n" /* skip tf_trapno and tf_errcode */
		"\tiret"
		: : "g" (tf) : "memory");
	panic("iret failed");  /* mostly to placate the compiler */
f0103103:	c7 44 24 08 7b 78 10 	movl   $0xf010787b,0x8(%esp)
f010310a:	f0 
f010310b:	c7 44 24 04 d6 01 00 	movl   $0x1d6,0x4(%esp)
f0103112:	00 
f0103113:	c7 04 24 87 78 10 f0 	movl   $0xf0107887,(%esp)
f010311a:	e8 66 cf ff ff       	call   f0100085 <_panic>

f010311f <env_run>:
//
// This function does not return.
//
void
env_run(struct Env *e)
{
f010311f:	55                   	push   %ebp
f0103120:	89 e5                	mov    %esp,%ebp
f0103122:	56                   	push   %esi
f0103123:	53                   	push   %ebx
f0103124:	83 ec 10             	sub    $0x10,%esp
f0103127:	8b 75 08             	mov    0x8(%ebp),%esi
	//	e->env_tf.  Go back through the code you wrote above
	//	and make sure you have set the relevant parts of
	//	e->env_tf to sensible values.
	
	// LAB 3: Your code here.
  curenv  = e;
f010312a:	89 35 60 f2 2c f0    	mov    %esi,0xf02cf260
  e->env_runs += 1;
f0103130:	83 46 58 01          	addl   $0x1,0x58(%esi)
f0103134:	bb 00 00 00 00       	mov    $0x0,%ebx
  for (i=0; i<NENV;i++) {
    if (envs[i].env_tf.tf_eip == 0 && envs[i].env_status == ENV_RUNNABLE)
f0103139:	89 d8                	mov    %ebx,%eax
f010313b:	03 05 5c f2 2c f0    	add    0xf02cf25c,%eax
f0103141:	83 78 30 00          	cmpl   $0x0,0x30(%eax)
f0103145:	75 19                	jne    f0103160 <env_run+0x41>
f0103147:	83 78 54 01          	cmpl   $0x1,0x54(%eax)
f010314b:	75 13                	jne    f0103160 <env_run+0x41>
      cprintf("Zero Env [%x]\n", envs[i].env_id);
f010314d:	8b 40 4c             	mov    0x4c(%eax),%eax
f0103150:	89 44 24 04          	mov    %eax,0x4(%esp)
f0103154:	c7 04 24 92 78 10 f0 	movl   $0xf0107892,(%esp)
f010315b:	e8 7f 08 00 00       	call   f01039df <cprintf>
f0103160:	83 c3 7c             	add    $0x7c,%ebx
	//	e->env_tf to sensible values.
	
	// LAB 3: Your code here.
  curenv  = e;
  e->env_runs += 1;
  for (i=0; i<NENV;i++) {
f0103163:	81 fb 00 f0 01 00    	cmp    $0x1f000,%ebx
f0103169:	75 ce                	jne    f0103139 <env_run+0x1a>
    if (envs[i].env_tf.tf_eip == 0 && envs[i].env_status == ENV_RUNNABLE)
      cprintf("Zero Env [%x]\n", envs[i].env_id);
  }
  lcr3(PADDR(e->env_pgdir));
f010316b:	8b 46 5c             	mov    0x5c(%esi),%eax
f010316e:	3d ff ff ff ef       	cmp    $0xefffffff,%eax
f0103173:	77 20                	ja     f0103195 <env_run+0x76>
f0103175:	89 44 24 0c          	mov    %eax,0xc(%esp)
f0103179:	c7 44 24 08 d0 70 10 	movl   $0xf01070d0,0x8(%esp)
f0103180:	f0 
f0103181:	c7 44 24 04 f7 01 00 	movl   $0x1f7,0x4(%esp)
f0103188:	00 
f0103189:	c7 04 24 87 78 10 f0 	movl   $0xf0107887,(%esp)
f0103190:	e8 f0 ce ff ff       	call   f0100085 <_panic>
f0103195:	05 00 00 00 10       	add    $0x10000000,%eax
f010319a:	0f 22 d8             	mov    %eax,%cr3
  env_pop_tf(&e->env_tf);
f010319d:	89 34 24             	mov    %esi,(%esp)
f01031a0:	e8 4e ff ff ff       	call   f01030f3 <env_pop_tf>

f01031a5 <env_free>:
//
// Frees env e and all memory it uses.
// 
void
env_free(struct Env *e)
{
f01031a5:	55                   	push   %ebp
f01031a6:	89 e5                	mov    %esp,%ebp
f01031a8:	57                   	push   %edi
f01031a9:	56                   	push   %esi
f01031aa:	53                   	push   %ebx
f01031ab:	83 ec 2c             	sub    $0x2c,%esp
f01031ae:	8b 7d 08             	mov    0x8(%ebp),%edi
	physaddr_t pa;
	
	// If freeing the current environment, switch to boot_pgdir
	// before freeing the page directory, just in case the page
	// gets reused.
	if (e == curenv)
f01031b1:	c7 45 e0 00 00 00 00 	movl   $0x0,-0x20(%ebp)
f01031b8:	3b 3d 60 f2 2c f0    	cmp    0xf02cf260,%edi
f01031be:	75 08                	jne    f01031c8 <env_free+0x23>
f01031c0:	a1 24 ff 2c f0       	mov    0xf02cff24,%eax
f01031c5:	0f 22 d8             	mov    %eax,%cr3
f01031c8:	8b 45 e0             	mov    -0x20(%ebp),%eax
f01031cb:	c1 e0 02             	shl    $0x2,%eax
f01031ce:	89 45 d8             	mov    %eax,-0x28(%ebp)
	// Flush all mapped pages in the user portion of the address space
	static_assert(UTOP % PTSIZE == 0);
	for (pdeno = 0; pdeno < PDX(UTOP); pdeno++) {

		// only look at mapped page tables
		if (!(e->env_pgdir[pdeno] & PTE_P))
f01031d1:	8b 47 5c             	mov    0x5c(%edi),%eax
f01031d4:	8b 55 d8             	mov    -0x28(%ebp),%edx
f01031d7:	8b 34 10             	mov    (%eax,%edx,1),%esi
f01031da:	f7 c6 01 00 00 00    	test   $0x1,%esi
f01031e0:	0f 84 bb 00 00 00    	je     f01032a1 <env_free+0xfc>
			continue;

		// find the pa and va of the page table
		pa = PTE_ADDR(e->env_pgdir[pdeno]);
f01031e6:	81 e6 00 f0 ff ff    	and    $0xfffff000,%esi
		pt = (pte_t*) KADDR(pa);
f01031ec:	89 f0                	mov    %esi,%eax
f01031ee:	c1 e8 0c             	shr    $0xc,%eax
f01031f1:	89 45 dc             	mov    %eax,-0x24(%ebp)
f01031f4:	3b 05 20 ff 2c f0    	cmp    0xf02cff20,%eax
f01031fa:	72 20                	jb     f010321c <env_free+0x77>
f01031fc:	89 74 24 0c          	mov    %esi,0xc(%esp)
f0103200:	c7 44 24 08 50 70 10 	movl   $0xf0107050,0x8(%esp)
f0103207:	f0 
f0103208:	c7 44 24 04 9d 01 00 	movl   $0x19d,0x4(%esp)
f010320f:	00 
f0103210:	c7 04 24 87 78 10 f0 	movl   $0xf0107887,(%esp)
f0103217:	e8 69 ce ff ff       	call   f0100085 <_panic>

		// unmap all PTEs in this page table
		for (pteno = 0; pteno < PTX(~0); pteno++) {
			if (pt[pteno] & PTE_P)
				page_remove(e->env_pgdir, PGADDR(pdeno, pteno, 0));
f010321c:	8b 55 e0             	mov    -0x20(%ebp),%edx
f010321f:	c1 e2 16             	shl    $0x16,%edx
f0103222:	89 55 e4             	mov    %edx,-0x1c(%ebp)
f0103225:	bb 00 00 00 00       	mov    $0x0,%ebx
		pa = PTE_ADDR(e->env_pgdir[pdeno]);
		pt = (pte_t*) KADDR(pa);

		// unmap all PTEs in this page table
		for (pteno = 0; pteno < PTX(~0); pteno++) {
			if (pt[pteno] & PTE_P)
f010322a:	f6 84 9e 00 00 00 f0 	testb  $0x1,-0x10000000(%esi,%ebx,4)
f0103231:	01 
f0103232:	74 17                	je     f010324b <env_free+0xa6>
				page_remove(e->env_pgdir, PGADDR(pdeno, pteno, 0));
f0103234:	89 d8                	mov    %ebx,%eax
f0103236:	c1 e0 0c             	shl    $0xc,%eax
f0103239:	0b 45 e4             	or     -0x1c(%ebp),%eax
f010323c:	89 44 24 04          	mov    %eax,0x4(%esp)
f0103240:	8b 47 5c             	mov    0x5c(%edi),%eax
f0103243:	89 04 24             	mov    %eax,(%esp)
f0103246:	e8 f4 e1 ff ff       	call   f010143f <page_remove>
		// find the pa and va of the page table
		pa = PTE_ADDR(e->env_pgdir[pdeno]);
		pt = (pte_t*) KADDR(pa);

		// unmap all PTEs in this page table
		for (pteno = 0; pteno < PTX(~0); pteno++) {
f010324b:	83 c3 01             	add    $0x1,%ebx
f010324e:	81 fb ff 03 00 00    	cmp    $0x3ff,%ebx
f0103254:	75 d4                	jne    f010322a <env_free+0x85>
			if (pt[pteno] & PTE_P)
				page_remove(e->env_pgdir, PGADDR(pdeno, pteno, 0));
		}

		// free the page table itself
		e->env_pgdir[pdeno] = 0;
f0103256:	8b 47 5c             	mov    0x5c(%edi),%eax
f0103259:	8b 55 d8             	mov    -0x28(%ebp),%edx
f010325c:	c7 04 10 00 00 00 00 	movl   $0x0,(%eax,%edx,1)
}

static inline struct Page*
pa2page(physaddr_t pa)
{
	if (PPN(pa) >= npage)
f0103263:	8b 45 dc             	mov    -0x24(%ebp),%eax
f0103266:	3b 05 20 ff 2c f0    	cmp    0xf02cff20,%eax
f010326c:	72 1c                	jb     f010328a <env_free+0xe5>
		panic("pa2page called with invalid pa");
f010326e:	c7 44 24 08 0c 6f 10 	movl   $0xf0106f0c,0x8(%esp)
f0103275:	f0 
f0103276:	c7 44 24 04 53 00 00 	movl   $0x53,0x4(%esp)
f010327d:	00 
f010327e:	c7 04 24 7d 6c 10 f0 	movl   $0xf0106c7d,(%esp)
f0103285:	e8 fb cd ff ff       	call   f0100085 <_panic>
		page_decref(pa2page(pa));
f010328a:	8b 55 dc             	mov    -0x24(%ebp),%edx
f010328d:	8d 04 52             	lea    (%edx,%edx,2),%eax
f0103290:	c1 e0 02             	shl    $0x2,%eax
f0103293:	03 05 2c ff 2c f0    	add    0xf02cff2c,%eax
f0103299:	89 04 24             	mov    %eax,(%esp)
f010329c:	e8 07 dd ff ff       	call   f0100fa8 <page_decref>
	// Note the environment's demise.
	// cprintf("[%08x] free env %08x\n", curenv ? curenv->env_id : 0, e->env_id);

	// Flush all mapped pages in the user portion of the address space
	static_assert(UTOP % PTSIZE == 0);
	for (pdeno = 0; pdeno < PDX(UTOP); pdeno++) {
f01032a1:	83 45 e0 01          	addl   $0x1,-0x20(%ebp)
f01032a5:	81 7d e0 bb 03 00 00 	cmpl   $0x3bb,-0x20(%ebp)
f01032ac:	0f 85 16 ff ff ff    	jne    f01031c8 <env_free+0x23>
		e->env_pgdir[pdeno] = 0;
		page_decref(pa2page(pa));
	}

	// free the page directory
	pa = e->env_cr3;
f01032b2:	8b 47 60             	mov    0x60(%edi),%eax
	e->env_pgdir = 0;
f01032b5:	c7 47 5c 00 00 00 00 	movl   $0x0,0x5c(%edi)
	e->env_cr3 = 0;
f01032bc:	c7 47 60 00 00 00 00 	movl   $0x0,0x60(%edi)
}

static inline struct Page*
pa2page(physaddr_t pa)
{
	if (PPN(pa) >= npage)
f01032c3:	c1 e8 0c             	shr    $0xc,%eax
f01032c6:	3b 05 20 ff 2c f0    	cmp    0xf02cff20,%eax
f01032cc:	72 1c                	jb     f01032ea <env_free+0x145>
		panic("pa2page called with invalid pa");
f01032ce:	c7 44 24 08 0c 6f 10 	movl   $0xf0106f0c,0x8(%esp)
f01032d5:	f0 
f01032d6:	c7 44 24 04 53 00 00 	movl   $0x53,0x4(%esp)
f01032dd:	00 
f01032de:	c7 04 24 7d 6c 10 f0 	movl   $0xf0106c7d,(%esp)
f01032e5:	e8 9b cd ff ff       	call   f0100085 <_panic>
	page_decref(pa2page(pa));
f01032ea:	6b c0 0c             	imul   $0xc,%eax,%eax
f01032ed:	03 05 2c ff 2c f0    	add    0xf02cff2c,%eax
f01032f3:	89 04 24             	mov    %eax,(%esp)
f01032f6:	e8 ad dc ff ff       	call   f0100fa8 <page_decref>

	// return the environment to the free list
	e->env_status = ENV_FREE;
f01032fb:	c7 47 54 00 00 00 00 	movl   $0x0,0x54(%edi)
	LIST_INSERT_HEAD(&env_free_list, e, env_link);
f0103302:	a1 64 f2 2c f0       	mov    0xf02cf264,%eax
f0103307:	89 47 44             	mov    %eax,0x44(%edi)
f010330a:	85 c0                	test   %eax,%eax
f010330c:	74 0b                	je     f0103319 <env_free+0x174>
f010330e:	8d 57 44             	lea    0x44(%edi),%edx
f0103311:	a1 64 f2 2c f0       	mov    0xf02cf264,%eax
f0103316:	89 50 48             	mov    %edx,0x48(%eax)
f0103319:	89 3d 64 f2 2c f0    	mov    %edi,0xf02cf264
f010331f:	c7 47 48 64 f2 2c f0 	movl   $0xf02cf264,0x48(%edi)
}
f0103326:	83 c4 2c             	add    $0x2c,%esp
f0103329:	5b                   	pop    %ebx
f010332a:	5e                   	pop    %esi
f010332b:	5f                   	pop    %edi
f010332c:	5d                   	pop    %ebp
f010332d:	c3                   	ret    

f010332e <env_destroy>:
// If e was the current env, then runs a new environment (and does not return
// to the caller).
//
void
env_destroy(struct Env *e) 
{
f010332e:	55                   	push   %ebp
f010332f:	89 e5                	mov    %esp,%ebp
f0103331:	53                   	push   %ebx
f0103332:	83 ec 14             	sub    $0x14,%esp
f0103335:	8b 5d 08             	mov    0x8(%ebp),%ebx
	env_free(e);
f0103338:	89 1c 24             	mov    %ebx,(%esp)
f010333b:	e8 65 fe ff ff       	call   f01031a5 <env_free>

	if (curenv == e) {
f0103340:	39 1d 60 f2 2c f0    	cmp    %ebx,0xf02cf260
f0103346:	75 0f                	jne    f0103357 <env_destroy+0x29>
		curenv = NULL;
f0103348:	c7 05 60 f2 2c f0 00 	movl   $0x0,0xf02cf260
f010334f:	00 00 00 
		sched_yield();
f0103352:	e8 39 13 00 00       	call   f0104690 <sched_yield>
	}
}
f0103357:	83 c4 14             	add    $0x14,%esp
f010335a:	5b                   	pop    %ebx
f010335b:	5d                   	pop    %ebp
f010335c:	c3                   	ret    

f010335d <env_init>:
// Insert in reverse order, so that the first call to env_alloc()
// returns envs[0].
//
void
env_init(void)
{
f010335d:	55                   	push   %ebp
f010335e:	89 e5                	mov    %esp,%ebp
f0103360:	53                   	push   %ebx
f0103361:	83 ec 14             	sub    $0x14,%esp
    int i;
    LIST_INIT(&env_free_list);
f0103364:	c7 05 64 f2 2c f0 00 	movl   $0x0,0xf02cf264
f010336b:	00 00 00 
f010336e:	bb 84 ef 01 00       	mov    $0x1ef84,%ebx
    for (i = NENV - 1; i >= 0; i--) {
      memset(&envs[i], 0, sizeof(struct Env));
f0103373:	c7 44 24 08 7c 00 00 	movl   $0x7c,0x8(%esp)
f010337a:	00 
f010337b:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
f0103382:	00 
f0103383:	89 d8                	mov    %ebx,%eax
f0103385:	03 05 5c f2 2c f0    	add    0xf02cf25c,%eax
f010338b:	89 04 24             	mov    %eax,(%esp)
f010338e:	e8 13 27 00 00       	call   f0105aa6 <memset>
      envs[i].env_id  = 0;
f0103393:	a1 5c f2 2c f0       	mov    0xf02cf25c,%eax
f0103398:	c7 44 18 4c 00 00 00 	movl   $0x0,0x4c(%eax,%ebx,1)
f010339f:	00 
	    LIST_INSERT_HEAD(&env_free_list, &envs[i], env_link);
f01033a0:	a1 64 f2 2c f0       	mov    0xf02cf264,%eax
f01033a5:	8b 15 5c f2 2c f0    	mov    0xf02cf25c,%edx
f01033ab:	89 44 1a 44          	mov    %eax,0x44(%edx,%ebx,1)
f01033af:	85 c0                	test   %eax,%eax
f01033b1:	74 13                	je     f01033c6 <env_init+0x69>
f01033b3:	89 da                	mov    %ebx,%edx
f01033b5:	03 15 5c f2 2c f0    	add    0xf02cf25c,%edx
f01033bb:	83 c2 44             	add    $0x44,%edx
f01033be:	a1 64 f2 2c f0       	mov    0xf02cf264,%eax
f01033c3:	89 50 48             	mov    %edx,0x48(%eax)
f01033c6:	89 d8                	mov    %ebx,%eax
f01033c8:	03 05 5c f2 2c f0    	add    0xf02cf25c,%eax
f01033ce:	a3 64 f2 2c f0       	mov    %eax,0xf02cf264
f01033d3:	c7 40 48 64 f2 2c f0 	movl   $0xf02cf264,0x48(%eax)
f01033da:	83 eb 7c             	sub    $0x7c,%ebx
void
env_init(void)
{
    int i;
    LIST_INIT(&env_free_list);
    for (i = NENV - 1; i >= 0; i--) {
f01033dd:	83 fb 84             	cmp    $0xffffff84,%ebx
f01033e0:	75 91                	jne    f0103373 <env_init+0x16>
      memset(&envs[i], 0, sizeof(struct Env));
      envs[i].env_id  = 0;
	    LIST_INSERT_HEAD(&env_free_list, &envs[i], env_link);
    }
}
f01033e2:	83 c4 14             	add    $0x14,%esp
f01033e5:	5b                   	pop    %ebx
f01033e6:	5d                   	pop    %ebp
f01033e7:	c3                   	ret    

f01033e8 <segment_alloc>:
// Pages should be writable by user and kernel.
// Panic if any allocation attempt fails.
//
static void
segment_alloc(struct Env *e, void *va, size_t len)
{
f01033e8:	55                   	push   %ebp
f01033e9:	89 e5                	mov    %esp,%ebp
f01033eb:	57                   	push   %edi
f01033ec:	56                   	push   %esi
f01033ed:	53                   	push   %ebx
f01033ee:	83 ec 3c             	sub    $0x3c,%esp
    int i;
    pde_t * pgdir   = e->env_pgdir;
f01033f1:	8b 70 5c             	mov    0x5c(%eax),%esi
	// (But only if you need it for load_icode.)
	//
	// Hint: It is easier to use segment_alloc if the caller can pass
	//   'va' and 'len' values that are not page-aligned.
	//   You should round va down, and round (va + len) up.
    if (pgdir != NULL) {
f01033f4:	85 f6                	test   %esi,%esi
f01033f6:	0f 84 d3 00 00 00    	je     f01034cf <segment_alloc+0xe7>
        uint32_t saddr  = (uint32_t)ROUNDDOWN(va, PGSIZE);
f01033fc:	89 d0                	mov    %edx,%eax
f01033fe:	25 00 f0 ff ff       	and    $0xfffff000,%eax
f0103403:	89 45 d0             	mov    %eax,-0x30(%ebp)
        uint32_t eaddr  = (uint32_t)ROUNDUP(va + len, PGSIZE);
f0103406:	8d 84 0a ff 0f 00 00 	lea    0xfff(%edx,%ecx,1),%eax
        int i,j;
        for (i = 0; i < (eaddr - saddr); i += PGSIZE) {
f010340d:	25 00 f0 ff ff       	and    $0xfffff000,%eax
f0103412:	2b 45 d0             	sub    -0x30(%ebp),%eax
f0103415:	89 45 cc             	mov    %eax,-0x34(%ebp)
f0103418:	0f 84 b1 00 00 00    	je     f01034cf <segment_alloc+0xe7>
f010341e:	b8 00 00 00 00       	mov    $0x0,%eax
f0103423:	bf 00 00 00 00       	mov    $0x0,%edi
            pte_t *pte  = pgdir_walk(pgdir, (void *)(saddr + i), 1);
f0103428:	03 45 d0             	add    -0x30(%ebp),%eax
f010342b:	89 45 d4             	mov    %eax,-0x2c(%ebp)
f010342e:	c7 44 24 08 01 00 00 	movl   $0x1,0x8(%esp)
f0103435:	00 
f0103436:	89 44 24 04          	mov    %eax,0x4(%esp)
f010343a:	89 34 24             	mov    %esi,(%esp)
f010343d:	e8 da dc ff ff       	call   f010111c <pgdir_walk>
f0103442:	89 c3                	mov    %eax,%ebx
            if (!(*pte & PTE_P)) {
f0103444:	f6 00 01             	testb  $0x1,(%eax)
f0103447:	75 68                	jne    f01034b1 <segment_alloc+0xc9>
                struct Page *p;
                if (page_alloc(&p)) {
f0103449:	8d 45 e4             	lea    -0x1c(%ebp),%eax
f010344c:	89 04 24             	mov    %eax,(%esp)
f010344f:	e8 77 dc ff ff       	call   f01010cb <page_alloc>
f0103454:	85 c0                	test   %eax,%eax
f0103456:	74 1c                	je     f0103474 <segment_alloc+0x8c>
                    panic("Out of memory");
f0103458:	c7 44 24 08 a1 78 10 	movl   $0xf01078a1,0x8(%esp)
f010345f:	f0 
f0103460:	c7 44 24 04 02 01 00 	movl   $0x102,0x4(%esp)
f0103467:	00 
f0103468:	c7 04 24 87 78 10 f0 	movl   $0xf0107887,(%esp)
f010346f:	e8 11 cc ff ff       	call   f0100085 <_panic>
                }
                memset(p, 0, sizeof(struct Page));
f0103474:	c7 44 24 08 0c 00 00 	movl   $0xc,0x8(%esp)
f010347b:	00 
f010347c:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
f0103483:	00 
f0103484:	8b 45 e4             	mov    -0x1c(%ebp),%eax
f0103487:	89 04 24             	mov    %eax,(%esp)
f010348a:	e8 17 26 00 00       	call   f0105aa6 <memset>
                p->pp_ref   += 1; 
f010348f:	8b 45 e4             	mov    -0x1c(%ebp),%eax
f0103492:	66 83 40 08 01       	addw   $0x1,0x8(%eax)
                *pte    = page2pa(p)|PTE_P|PTE_W|PTE_U; 
f0103497:	8b 45 e4             	mov    -0x1c(%ebp),%eax
f010349a:	2b 05 2c ff 2c f0    	sub    0xf02cff2c,%eax
f01034a0:	c1 f8 02             	sar    $0x2,%eax
f01034a3:	69 c0 ab aa aa aa    	imul   $0xaaaaaaab,%eax,%eax
f01034a9:	c1 e0 0c             	shl    $0xc,%eax
f01034ac:	83 c8 07             	or     $0x7,%eax
f01034af:	89 03                	mov    %eax,(%ebx)
            }
            *pte    = *pte|PTE_P|PTE_W|PTE_U; 
f01034b1:	83 0b 07             	orl    $0x7,(%ebx)
            pgdir [PDX(saddr+i)]    = pgdir [PDX(saddr+i)]|PTE_P|PTE_W|PTE_U;
f01034b4:	8b 45 d4             	mov    -0x2c(%ebp),%eax
f01034b7:	c1 e8 16             	shr    $0x16,%eax
f01034ba:	83 0c 86 07          	orl    $0x7,(%esi,%eax,4)
	//   You should round va down, and round (va + len) up.
    if (pgdir != NULL) {
        uint32_t saddr  = (uint32_t)ROUNDDOWN(va, PGSIZE);
        uint32_t eaddr  = (uint32_t)ROUNDUP(va + len, PGSIZE);
        int i,j;
        for (i = 0; i < (eaddr - saddr); i += PGSIZE) {
f01034be:	81 c7 00 10 00 00    	add    $0x1000,%edi
f01034c4:	89 f8                	mov    %edi,%eax
f01034c6:	39 7d cc             	cmp    %edi,-0x34(%ebp)
f01034c9:	0f 87 59 ff ff ff    	ja     f0103428 <segment_alloc+0x40>
            }
            *pte    = *pte|PTE_P|PTE_W|PTE_U; 
            pgdir [PDX(saddr+i)]    = pgdir [PDX(saddr+i)]|PTE_P|PTE_W|PTE_U;
        }
    }
}
f01034cf:	83 c4 3c             	add    $0x3c,%esp
f01034d2:	5b                   	pop    %ebx
f01034d3:	5e                   	pop    %esi
f01034d4:	5f                   	pop    %edi
f01034d5:	5d                   	pop    %ebp
f01034d6:	c3                   	ret    

f01034d7 <env_alloc>:
//	-E_NO_FREE_ENV if all NENVS environments are allocated
//	-E_NO_MEM on memory exhaustion
//
int
env_alloc(struct Env **newenv_store, envid_t parent_id)
{
f01034d7:	55                   	push   %ebp
f01034d8:	89 e5                	mov    %esp,%ebp
f01034da:	53                   	push   %ebx
f01034db:	83 ec 24             	sub    $0x24,%esp
	int32_t generation;
	int r;
	struct Env *e;

	if (!(e = LIST_FIRST(&env_free_list)))
f01034de:	8b 1d 64 f2 2c f0    	mov    0xf02cf264,%ebx
f01034e4:	b8 fb ff ff ff       	mov    $0xfffffffb,%eax
f01034e9:	85 db                	test   %ebx,%ebx
f01034eb:	0f 84 d2 01 00 00    	je     f01036c3 <env_alloc+0x1ec>

static int
env_setup_vm(struct Env *e)
{
	int i, r;
	struct Page *p = NULL;
f01034f1:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)
  uint32_t va;
  struct Page *kstack = NULL;
  pte_t *pt = NULL;

	// Allocate a page for the page directory
	if ((r = page_alloc(&p)) < 0)
f01034f8:	8d 45 f4             	lea    -0xc(%ebp),%eax
f01034fb:	89 04 24             	mov    %eax,(%esp)
f01034fe:	e8 c8 db ff ff       	call   f01010cb <page_alloc>
f0103503:	85 c0                	test   %eax,%eax
f0103505:	0f 88 b8 01 00 00    	js     f01036c3 <env_alloc+0x1ec>
	//	is an exception -- you need to increment env_pgdir's
	//	pp_ref for env_free to work correctly.
	//    - The functions in kern/pmap.h are handy.

	// LAB 3: Your code here.
  memset(p, 0, sizeof(struct Page));
f010350b:	c7 44 24 08 0c 00 00 	movl   $0xc,0x8(%esp)
f0103512:	00 
f0103513:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
f010351a:	00 
f010351b:	8b 45 f4             	mov    -0xc(%ebp),%eax
f010351e:	89 04 24             	mov    %eax,(%esp)
f0103521:	e8 80 25 00 00       	call   f0105aa6 <memset>
  p->pp_ref       += 1;
f0103526:	8b 45 f4             	mov    -0xc(%ebp),%eax
f0103529:	66 83 40 08 01       	addw   $0x1,0x8(%eax)
}

static inline physaddr_t
page2pa(struct Page *pp)
{
	return page2ppn(pp) << PGSHIFT;
f010352e:	8b 45 f4             	mov    -0xc(%ebp),%eax
f0103531:	2b 05 2c ff 2c f0    	sub    0xf02cff2c,%eax
f0103537:	c1 f8 02             	sar    $0x2,%eax
f010353a:	69 c0 ab aa aa aa    	imul   $0xaaaaaaab,%eax,%eax
f0103540:	c1 e0 0c             	shl    $0xc,%eax
}

static inline void*
page2kva(struct Page *pp)
{
	return KADDR(page2pa(pp));
f0103543:	89 c2                	mov    %eax,%edx
f0103545:	c1 ea 0c             	shr    $0xc,%edx
f0103548:	3b 15 20 ff 2c f0    	cmp    0xf02cff20,%edx
f010354e:	72 20                	jb     f0103570 <env_alloc+0x99>
f0103550:	89 44 24 0c          	mov    %eax,0xc(%esp)
f0103554:	c7 44 24 08 50 70 10 	movl   $0xf0107050,0x8(%esp)
f010355b:	f0 
f010355c:	c7 44 24 04 5a 00 00 	movl   $0x5a,0x4(%esp)
f0103563:	00 
f0103564:	c7 04 24 7d 6c 10 f0 	movl   $0xf0106c7d,(%esp)
f010356b:	e8 15 cb ff ff       	call   f0100085 <_panic>
  e->env_pgdir    = page2kva(p);
f0103570:	2d 00 00 00 10       	sub    $0x10000000,%eax
f0103575:	89 43 5c             	mov    %eax,0x5c(%ebx)
  e->env_cr3      = page2pa(p);
f0103578:	8b 55 f4             	mov    -0xc(%ebp),%edx
f010357b:	2b 15 2c ff 2c f0    	sub    0xf02cff2c,%edx
f0103581:	c1 fa 02             	sar    $0x2,%edx
f0103584:	69 d2 ab aa aa aa    	imul   $0xaaaaaaab,%edx,%edx
f010358a:	c1 e2 0c             	shl    $0xc,%edx
f010358d:	89 53 60             	mov    %edx,0x60(%ebx)

  memset(e->env_pgdir, 0, PGSIZE);
f0103590:	c7 44 24 08 00 10 00 	movl   $0x1000,0x8(%esp)
f0103597:	00 
f0103598:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
f010359f:	00 
f01035a0:	89 04 24             	mov    %eax,(%esp)
f01035a3:	e8 fe 24 00 00       	call   f0105aa6 <memset>
f01035a8:	b8 ec 0e 00 00       	mov    $0xeec,%eax
  for (i=PDX(UTOP); i < NPDENTRIES; i++) {
      e->env_pgdir[i] = boot_pgdir[i];
f01035ad:	8b 53 5c             	mov    0x5c(%ebx),%edx
f01035b0:	8b 0d 28 ff 2c f0    	mov    0xf02cff28,%ecx
f01035b6:	8b 0c 01             	mov    (%ecx,%eax,1),%ecx
f01035b9:	89 0c 02             	mov    %ecx,(%edx,%eax,1)
f01035bc:	83 c0 04             	add    $0x4,%eax
  p->pp_ref       += 1;
  e->env_pgdir    = page2kva(p);
  e->env_cr3      = page2pa(p);

  memset(e->env_pgdir, 0, PGSIZE);
  for (i=PDX(UTOP); i < NPDENTRIES; i++) {
f01035bf:	3d 00 10 00 00       	cmp    $0x1000,%eax
f01035c4:	75 e7                	jne    f01035ad <env_alloc+0xd6>
f01035c6:	ba 00 00 00 00       	mov    $0x0,%edx
f01035cb:	66 b8 00 00          	mov    $0x0,%ax
      e->env_pgdir[i] = boot_pgdir[i];
  }

  for (i=0; i<PDX(USTACKTOP); i++) {
      e->env_pgdir[i] = 0;
f01035cf:	8b 4b 5c             	mov    0x5c(%ebx),%ecx
f01035d2:	c7 04 91 00 00 00 00 	movl   $0x0,(%ecx,%edx,4)
  memset(e->env_pgdir, 0, PGSIZE);
  for (i=PDX(UTOP); i < NPDENTRIES; i++) {
      e->env_pgdir[i] = boot_pgdir[i];
  }

  for (i=0; i<PDX(USTACKTOP); i++) {
f01035d9:	83 c0 01             	add    $0x1,%eax
f01035dc:	89 c2                	mov    %eax,%edx
f01035de:	3d ba 03 00 00       	cmp    $0x3ba,%eax
f01035e3:	75 ea                	jne    f01035cf <env_alloc+0xf8>
      e->env_pgdir[i] = 0;
  }

	// VPT and UVPT map the env's own page table, with
	// different permissions.
	e->env_pgdir[PDX(VPT)]  = e->env_cr3 | PTE_P | PTE_W;
f01035e5:	8b 43 5c             	mov    0x5c(%ebx),%eax
f01035e8:	8b 53 60             	mov    0x60(%ebx),%edx
f01035eb:	83 ca 03             	or     $0x3,%edx
f01035ee:	89 90 fc 0e 00 00    	mov    %edx,0xefc(%eax)
	e->env_pgdir[PDX(UVPT)] = e->env_cr3 | PTE_P | PTE_U;
f01035f4:	8b 43 5c             	mov    0x5c(%ebx),%eax
f01035f7:	8b 53 60             	mov    0x60(%ebx),%edx
f01035fa:	83 ca 05             	or     $0x5,%edx
f01035fd:	89 90 f4 0e 00 00    	mov    %edx,0xef4(%eax)
	// Allocate and set up the page directory for this environment.
	if ((r = env_setup_vm(e)) < 0)
		return r;

	// Generate an env_id for this environment.
	generation = (e->env_id + (1 << ENVGENSHIFT)) & ~(NENV - 1);
f0103603:	8b 43 4c             	mov    0x4c(%ebx),%eax
f0103606:	05 00 10 00 00       	add    $0x1000,%eax
	if (generation <= 0)	// Don't create a negative env_id.
f010360b:	25 00 fc ff ff       	and    $0xfffffc00,%eax
f0103610:	ba 00 10 00 00       	mov    $0x1000,%edx
f0103615:	0f 4e c2             	cmovle %edx,%eax
		generation = 1 << ENVGENSHIFT;
	e->env_id = generation | (e - envs);
f0103618:	89 da                	mov    %ebx,%edx
f010361a:	2b 15 5c f2 2c f0    	sub    0xf02cf25c,%edx
f0103620:	c1 fa 02             	sar    $0x2,%edx
f0103623:	69 d2 df 7b ef bd    	imul   $0xbdef7bdf,%edx,%edx
f0103629:	09 d0                	or     %edx,%eax
f010362b:	89 43 4c             	mov    %eax,0x4c(%ebx)
	
	// Set the basic status variables.
	e->env_parent_id = parent_id;
f010362e:	8b 45 0c             	mov    0xc(%ebp),%eax
f0103631:	89 43 50             	mov    %eax,0x50(%ebx)
	e->env_status = ENV_RUNNABLE;
f0103634:	c7 43 54 01 00 00 00 	movl   $0x1,0x54(%ebx)
	e->env_runs = 0;
f010363b:	c7 43 58 00 00 00 00 	movl   $0x0,0x58(%ebx)

	// Clear out all the saved register state,
	// to prevent the register values
	// of a prior environment inhabiting this Env structure
	// from "leaking" into our new environment.
	memset(&e->env_tf, 0, sizeof(e->env_tf));
f0103642:	c7 44 24 08 44 00 00 	movl   $0x44,0x8(%esp)
f0103649:	00 
f010364a:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
f0103651:	00 
f0103652:	89 1c 24             	mov    %ebx,(%esp)
f0103655:	e8 4c 24 00 00       	call   f0105aa6 <memset>
	// Set up appropriate initial values for the segment registers.
	// GD_UD is the user data segment selector in the GDT, and 
	// GD_UT is the user text segment selector (see inc/memlayout.h).
	// The low 2 bits of each segment register contains the
	// Requestor Privilege Level (RPL); 3 means user mode.
	e->env_tf.tf_ds   = GD_UD | 3;
f010365a:	66 c7 43 24 23 00    	movw   $0x23,0x24(%ebx)
	e->env_tf.tf_es   = GD_UD | 3;
f0103660:	66 c7 43 20 23 00    	movw   $0x23,0x20(%ebx)
	e->env_tf.tf_ss   = GD_UD | 3;
f0103666:	66 c7 43 40 23 00    	movw   $0x23,0x40(%ebx)
	e->env_tf.tf_esp  = USTACKTOP;
f010366c:	c7 43 3c 00 e0 bf ee 	movl   $0xeebfe000,0x3c(%ebx)
	e->env_tf.tf_cs   = GD_UT | 3;
f0103673:	66 c7 43 34 1b 00    	movw   $0x1b,0x34(%ebx)
  e->env_tf.tf_eflags |= FL_IF;
f0103679:	8b 43 38             	mov    0x38(%ebx),%eax
f010367c:	80 cc 02             	or     $0x2,%ah
f010367f:	89 43 38             	mov    %eax,0x38(%ebx)
  
  if (ENVX(e->env_id) == 1) {
f0103682:	8b 53 4c             	mov    0x4c(%ebx),%edx
f0103685:	81 e2 ff 03 00 00    	and    $0x3ff,%edx
f010368b:	83 fa 01             	cmp    $0x1,%edx
f010368e:	75 06                	jne    f0103696 <env_alloc+0x1bf>
      e->env_tf.tf_eflags  |= FL_IOPL_MASK;
f0103690:	80 cc 30             	or     $0x30,%ah
f0103693:	89 43 38             	mov    %eax,0x38(%ebx)

	// Enable interrupts while in user mode.
	// LAB 4: Your code here.

	// Clear the page fault handler until user installs one.
	e->env_pgfault_upcall = 0;
f0103696:	c7 43 64 00 00 00 00 	movl   $0x0,0x64(%ebx)

	// Also clear the IPC receiving flag.
	e->env_ipc_recving = 0;
f010369d:	c7 43 68 00 00 00 00 	movl   $0x0,0x68(%ebx)

	// If this is the file server (e == &envs[1]) give it I/O privileges.
	// LAB 5: Your code here.

	// commit the allocation
	LIST_REMOVE(e, env_link);
f01036a4:	8b 43 44             	mov    0x44(%ebx),%eax
f01036a7:	85 c0                	test   %eax,%eax
f01036a9:	74 06                	je     f01036b1 <env_alloc+0x1da>
f01036ab:	8b 53 48             	mov    0x48(%ebx),%edx
f01036ae:	89 50 48             	mov    %edx,0x48(%eax)
f01036b1:	8b 43 48             	mov    0x48(%ebx),%eax
f01036b4:	8b 53 44             	mov    0x44(%ebx),%edx
f01036b7:	89 10                	mov    %edx,(%eax)
	*newenv_store = e;
f01036b9:	8b 45 08             	mov    0x8(%ebp),%eax
f01036bc:	89 18                	mov    %ebx,(%eax)
f01036be:	b8 00 00 00 00       	mov    $0x0,%eax

	// cprintf("[%08x] new env %08x\n", curenv ? curenv->env_id : 0, e->env_id);
	return 0;
}
f01036c3:	83 c4 24             	add    $0x24,%esp
f01036c6:	5b                   	pop    %ebx
f01036c7:	5d                   	pop    %ebp
f01036c8:	c3                   	ret    

f01036c9 <env_create>:
// The new env's parent ID is set to 0.
//

void
env_create(uint8_t *binary, size_t size)
{
f01036c9:	55                   	push   %ebp
f01036ca:	89 e5                	mov    %esp,%ebp
f01036cc:	57                   	push   %edi
f01036cd:	56                   	push   %esi
f01036ce:	53                   	push   %ebx
f01036cf:	83 ec 3c             	sub    $0x3c,%esp
    struct Env *env;
    int r;
    if (!(r=env_alloc(&env, 0))) {
f01036d2:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
f01036d9:	00 
f01036da:	8d 45 e4             	lea    -0x1c(%ebp),%eax
f01036dd:	89 04 24             	mov    %eax,(%esp)
f01036e0:	e8 f2 fd ff ff       	call   f01034d7 <env_alloc>
f01036e5:	85 c0                	test   %eax,%eax
f01036e7:	0f 85 17 01 00 00    	jne    f0103804 <env_create+0x13b>
        load_icode(env, binary, size);
f01036ed:	8b 45 e4             	mov    -0x1c(%ebp),%eax
f01036f0:	89 45 d4             	mov    %eax,-0x2c(%ebp)
//  - How might load_icode fail?  What might be wrong with the given input?
//
static void
load_icode(struct Env *e, uint8_t *binary, size_t size)
{
    struct Elf *elf = (struct Elf *)binary;
f01036f3:	8b 7d 08             	mov    0x8(%ebp),%edi

	// Now map one page for the program's initial stack
	// at virtual address USTACKTOP - PGSIZE.

	// LAB 3: Your code here.
    if (elf && elf->e_magic == ELF_MAGIC) {
f01036f6:	85 ff                	test   %edi,%edi
f01036f8:	0f 84 ea 00 00 00    	je     f01037e8 <env_create+0x11f>
f01036fe:	81 3f 7f 45 4c 46    	cmpl   $0x464c457f,(%edi)
f0103704:	0f 85 de 00 00 00    	jne    f01037e8 <env_create+0x11f>
	//  The ph->p_filesz bytes from the ELF binary, starting at
	//  'binary + ph->p_offset', should be copied to virtual address
	//  ph->p_va.  Any remaining memory bytes should be cleared to zero.
	//  (The ELF header should have ph->p_filesz <= ph->p_memsz.)
	//  Use functions from the previous lab to allocate and map pages.
        ph  = (struct Proghdr *)((uint8_t *)elf + elf->e_phoff);
f010370a:	89 fb                	mov    %edi,%ebx
f010370c:	03 5f 1c             	add    0x1c(%edi),%ebx
        eph = ph + elf->e_phnum;
f010370f:	0f b7 77 2c          	movzwl 0x2c(%edi),%esi
f0103713:	c1 e6 05             	shl    $0x5,%esi
f0103716:	8d 34 33             	lea    (%ebx,%esi,1),%esi
        for(;ph < eph; ph++) {
f0103719:	39 f3                	cmp    %esi,%ebx
f010371b:	0f 83 9d 00 00 00    	jae    f01037be <env_create+0xf5>
            if (ph->p_type == ELF_PROG_LOAD) {
f0103721:	83 3b 01             	cmpl   $0x1,(%ebx)
f0103724:	0f 85 89 00 00 00    	jne    f01037b3 <env_create+0xea>
                segment_alloc(e, (void *)ph->p_va, ph->p_memsz);
f010372a:	8b 4b 14             	mov    0x14(%ebx),%ecx
f010372d:	8b 53 08             	mov    0x8(%ebx),%edx
f0103730:	8b 45 d4             	mov    -0x2c(%ebp),%eax
f0103733:	e8 b0 fc ff ff       	call   f01033e8 <segment_alloc>
                lcr3(PADDR((uint32_t)e->env_pgdir));
f0103738:	8b 55 d4             	mov    -0x2c(%ebp),%edx
f010373b:	8b 42 5c             	mov    0x5c(%edx),%eax
f010373e:	3d ff ff ff ef       	cmp    $0xefffffff,%eax
f0103743:	77 20                	ja     f0103765 <env_create+0x9c>
f0103745:	89 44 24 0c          	mov    %eax,0xc(%esp)
f0103749:	c7 44 24 08 d0 70 10 	movl   $0xf01070d0,0x8(%esp)
f0103750:	f0 
f0103751:	c7 44 24 04 5b 01 00 	movl   $0x15b,0x4(%esp)
f0103758:	00 
f0103759:	c7 04 24 87 78 10 f0 	movl   $0xf0107887,(%esp)
f0103760:	e8 20 c9 ff ff       	call   f0100085 <_panic>
f0103765:	05 00 00 00 10       	add    $0x10000000,%eax
f010376a:	0f 22 d8             	mov    %eax,%cr3
                memmove((void *)ph->p_va, (void *)((uint8_t *)elf + ph->p_offset), ph->p_filesz);
f010376d:	8b 43 10             	mov    0x10(%ebx),%eax
f0103770:	89 44 24 08          	mov    %eax,0x8(%esp)
f0103774:	89 f8                	mov    %edi,%eax
f0103776:	03 43 04             	add    0x4(%ebx),%eax
f0103779:	89 44 24 04          	mov    %eax,0x4(%esp)
f010377d:	8b 43 08             	mov    0x8(%ebx),%eax
f0103780:	89 04 24             	mov    %eax,(%esp)
f0103783:	e8 7d 23 00 00       	call   f0105b05 <memmove>
                if (ph->p_filesz < ph->p_memsz) {
f0103788:	8b 43 10             	mov    0x10(%ebx),%eax
f010378b:	8b 53 14             	mov    0x14(%ebx),%edx
f010378e:	39 d0                	cmp    %edx,%eax
f0103790:	73 19                	jae    f01037ab <env_create+0xe2>
                    memset((void *)(ph->p_va + ph->p_filesz), 0, ph->p_memsz-ph->p_filesz);
f0103792:	29 c2                	sub    %eax,%edx
f0103794:	89 54 24 08          	mov    %edx,0x8(%esp)
f0103798:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
f010379f:	00 
f01037a0:	03 43 08             	add    0x8(%ebx),%eax
f01037a3:	89 04 24             	mov    %eax,(%esp)
f01037a6:	e8 fb 22 00 00       	call   f0105aa6 <memset>
f01037ab:	a1 24 ff 2c f0       	mov    0xf02cff24,%eax
f01037b0:	0f 22 d8             	mov    %eax,%cr3
	//  ph->p_va.  Any remaining memory bytes should be cleared to zero.
	//  (The ELF header should have ph->p_filesz <= ph->p_memsz.)
	//  Use functions from the previous lab to allocate and map pages.
        ph  = (struct Proghdr *)((uint8_t *)elf + elf->e_phoff);
        eph = ph + elf->e_phnum;
        for(;ph < eph; ph++) {
f01037b3:	83 c3 20             	add    $0x20,%ebx
f01037b6:	39 de                	cmp    %ebx,%esi
f01037b8:	0f 87 63 ff ff ff    	ja     f0103721 <env_create+0x58>
                    memset((void *)(ph->p_va + ph->p_filesz), 0, ph->p_memsz-ph->p_filesz);
                }
                lcr3(boot_cr3);
            }
        }
        segment_alloc(e, (void *)(USTACKTOP-PGSIZE), PGSIZE);
f01037be:	b9 00 10 00 00       	mov    $0x1000,%ecx
f01037c3:	ba 00 d0 bf ee       	mov    $0xeebfd000,%edx
f01037c8:	8b 45 d4             	mov    -0x2c(%ebp),%eax
f01037cb:	e8 18 fc ff ff       	call   f01033e8 <segment_alloc>
        e->env_tf.tf_eip    = elf->e_entry;
f01037d0:	8b 47 18             	mov    0x18(%edi),%eax
f01037d3:	8b 55 d4             	mov    -0x2c(%ebp),%edx
f01037d6:	89 42 30             	mov    %eax,0x30(%edx)
        e->env_tf.tf_esp    = USTACKTOP;
f01037d9:	c7 42 3c 00 e0 bf ee 	movl   $0xeebfe000,0x3c(%edx)
        load_icode(env, binary, size);
    } else {
        panic("Failed: %e", r);
    }
	// LAB 3: Your code here.
}
f01037e0:	83 c4 3c             	add    $0x3c,%esp
f01037e3:	5b                   	pop    %ebx
f01037e4:	5e                   	pop    %esi
f01037e5:	5f                   	pop    %edi
f01037e6:	5d                   	pop    %ebp
f01037e7:	c3                   	ret    
        }
        segment_alloc(e, (void *)(USTACKTOP-PGSIZE), PGSIZE);
        e->env_tf.tf_eip    = elf->e_entry;
        e->env_tf.tf_esp    = USTACKTOP;
    } else {
        panic("Invalid Binary");
f01037e8:	c7 44 24 08 af 78 10 	movl   $0xf01078af,0x8(%esp)
f01037ef:	f0 
f01037f0:	c7 44 24 04 67 01 00 	movl   $0x167,0x4(%esp)
f01037f7:	00 
f01037f8:	c7 04 24 87 78 10 f0 	movl   $0xf0107887,(%esp)
f01037ff:	e8 81 c8 ff ff       	call   f0100085 <_panic>
    struct Env *env;
    int r;
    if (!(r=env_alloc(&env, 0))) {
        load_icode(env, binary, size);
    } else {
        panic("Failed: %e", r);
f0103804:	89 44 24 0c          	mov    %eax,0xc(%esp)
f0103808:	c7 44 24 08 be 78 10 	movl   $0xf01078be,0x8(%esp)
f010380f:	f0 
f0103810:	c7 44 24 04 7b 01 00 	movl   $0x17b,0x4(%esp)
f0103817:	00 
f0103818:	c7 04 24 87 78 10 f0 	movl   $0xf0107887,(%esp)
f010381f:	e8 61 c8 ff ff       	call   f0100085 <_panic>

f0103824 <mc146818_read>:
#include <kern/picirq.h>


unsigned
mc146818_read(unsigned reg)
{
f0103824:	55                   	push   %ebp
f0103825:	89 e5                	mov    %esp,%ebp
}

static __inline void
outb(int port, uint8_t data)
{
	__asm __volatile("outb %0,%w1" : : "a" (data), "d" (port));
f0103827:	ba 70 00 00 00       	mov    $0x70,%edx
f010382c:	8b 45 08             	mov    0x8(%ebp),%eax
f010382f:	ee                   	out    %al,(%dx)

static __inline uint8_t
inb(int port)
{
	uint8_t data;
	__asm __volatile("inb %w1,%0" : "=a" (data) : "d" (port));
f0103830:	b2 71                	mov    $0x71,%dl
f0103832:	ec                   	in     (%dx),%al
f0103833:	0f b6 c0             	movzbl %al,%eax
	outb(IO_RTC, reg);
	return inb(IO_RTC+1);
}
f0103836:	5d                   	pop    %ebp
f0103837:	c3                   	ret    

f0103838 <mc146818_write>:

void
mc146818_write(unsigned reg, unsigned datum)
{
f0103838:	55                   	push   %ebp
f0103839:	89 e5                	mov    %esp,%ebp
}

static __inline void
outb(int port, uint8_t data)
{
	__asm __volatile("outb %0,%w1" : : "a" (data), "d" (port));
f010383b:	ba 70 00 00 00       	mov    $0x70,%edx
f0103840:	8b 45 08             	mov    0x8(%ebp),%eax
f0103843:	ee                   	out    %al,(%dx)
f0103844:	b2 71                	mov    $0x71,%dl
f0103846:	8b 45 0c             	mov    0xc(%ebp),%eax
f0103849:	ee                   	out    %al,(%dx)
	outb(IO_RTC, reg);
	outb(IO_RTC+1, datum);
}
f010384a:	5d                   	pop    %ebp
f010384b:	c3                   	ret    

f010384c <kclock_init>:


void
kclock_init(void)
{
f010384c:	55                   	push   %ebp
f010384d:	89 e5                	mov    %esp,%ebp
f010384f:	83 ec 18             	sub    $0x18,%esp
f0103852:	ba 43 00 00 00       	mov    $0x43,%edx
f0103857:	b8 34 00 00 00       	mov    $0x34,%eax
f010385c:	ee                   	out    %al,(%dx)
f010385d:	b2 40                	mov    $0x40,%dl
f010385f:	b8 9c ff ff ff       	mov    $0xffffff9c,%eax
f0103864:	ee                   	out    %al,(%dx)
f0103865:	b8 2e 00 00 00       	mov    $0x2e,%eax
f010386a:	ee                   	out    %al,(%dx)
	/* initialize 8253 clock to interrupt 100 times/sec */
	outb(TIMER_MODE, TIMER_SEL0 | TIMER_RATEGEN | TIMER_16BIT);
	outb(IO_TIMER1, TIMER_DIV(100) % 256);
	outb(IO_TIMER1, TIMER_DIV(100) / 256);
	cprintf("	Setup timer interrupts via 8259A\n");
f010386b:	c7 04 24 cc 78 10 f0 	movl   $0xf01078cc,(%esp)
f0103872:	e8 68 01 00 00       	call   f01039df <cprintf>
	irq_setmask_8259A(irq_mask_8259A & ~(1<<0));
f0103877:	0f b7 05 b8 e3 11 f0 	movzwl 0xf011e3b8,%eax
f010387e:	25 fe ff 00 00       	and    $0xfffe,%eax
f0103883:	89 04 24             	mov    %eax,(%esp)
f0103886:	e8 24 00 00 00       	call   f01038af <irq_setmask_8259A>
	cprintf("	unmasked timer interrupt\n");
f010388b:	c7 04 24 ef 78 10 f0 	movl   $0xf01078ef,(%esp)
f0103892:	e8 48 01 00 00       	call   f01039df <cprintf>
}
f0103897:	c9                   	leave  
f0103898:	c3                   	ret    
f0103899:	00 00                	add    %al,(%eax)
	...

f010389c <irq_eoi>:
	cprintf("\n");
}

void
irq_eoi(void)
{
f010389c:	55                   	push   %ebp
f010389d:	89 e5                	mov    %esp,%ebp
f010389f:	ba 20 00 00 00       	mov    $0x20,%edx
f01038a4:	b8 20 00 00 00       	mov    $0x20,%eax
f01038a9:	ee                   	out    %al,(%dx)
f01038aa:	b2 a0                	mov    $0xa0,%dl
f01038ac:	ee                   	out    %al,(%dx)
	//   s: specific
	//   e: end-of-interrupt
	// xxx: specific interrupt line
	outb(IO_PIC1, 0x20);
	outb(IO_PIC2, 0x20);
}
f01038ad:	5d                   	pop    %ebp
f01038ae:	c3                   	ret    

f01038af <irq_setmask_8259A>:
		irq_setmask_8259A(irq_mask_8259A);
}

void
irq_setmask_8259A(uint16_t mask)
{
f01038af:	55                   	push   %ebp
f01038b0:	89 e5                	mov    %esp,%ebp
f01038b2:	56                   	push   %esi
f01038b3:	53                   	push   %ebx
f01038b4:	83 ec 10             	sub    $0x10,%esp
f01038b7:	8b 45 08             	mov    0x8(%ebp),%eax
f01038ba:	89 c6                	mov    %eax,%esi
	int i;
	irq_mask_8259A = mask;
f01038bc:	66 a3 b8 e3 11 f0    	mov    %ax,0xf011e3b8
	if (!didinit)
f01038c2:	83 3d 68 f2 2c f0 00 	cmpl   $0x0,0xf02cf268
f01038c9:	74 4e                	je     f0103919 <irq_setmask_8259A+0x6a>
f01038cb:	ba 21 00 00 00       	mov    $0x21,%edx
f01038d0:	ee                   	out    %al,(%dx)
f01038d1:	89 f0                	mov    %esi,%eax
f01038d3:	66 c1 e8 08          	shr    $0x8,%ax
f01038d7:	b2 a1                	mov    $0xa1,%dl
f01038d9:	ee                   	out    %al,(%dx)
		return;
	outb(IO_PIC1+1, (char)mask);
	outb(IO_PIC2+1, (char)(mask >> 8));
	cprintf("enabled interrupts:");
f01038da:	c7 04 24 0a 79 10 f0 	movl   $0xf010790a,(%esp)
f01038e1:	e8 f9 00 00 00       	call   f01039df <cprintf>
f01038e6:	bb 00 00 00 00       	mov    $0x0,%ebx
	for (i = 0; i < 16; i++)
		if (~mask & (1<<i))
f01038eb:	0f b7 f6             	movzwl %si,%esi
f01038ee:	f7 d6                	not    %esi
f01038f0:	0f a3 de             	bt     %ebx,%esi
f01038f3:	73 10                	jae    f0103905 <irq_setmask_8259A+0x56>
			cprintf(" %d", i);
f01038f5:	89 5c 24 04          	mov    %ebx,0x4(%esp)
f01038f9:	c7 04 24 74 7e 10 f0 	movl   $0xf0107e74,(%esp)
f0103900:	e8 da 00 00 00       	call   f01039df <cprintf>
	if (!didinit)
		return;
	outb(IO_PIC1+1, (char)mask);
	outb(IO_PIC2+1, (char)(mask >> 8));
	cprintf("enabled interrupts:");
	for (i = 0; i < 16; i++)
f0103905:	83 c3 01             	add    $0x1,%ebx
f0103908:	83 fb 10             	cmp    $0x10,%ebx
f010390b:	75 e3                	jne    f01038f0 <irq_setmask_8259A+0x41>
		if (~mask & (1<<i))
			cprintf(" %d", i);
	cprintf("\n");
f010390d:	c7 04 24 62 78 10 f0 	movl   $0xf0107862,(%esp)
f0103914:	e8 c6 00 00 00       	call   f01039df <cprintf>
}
f0103919:	83 c4 10             	add    $0x10,%esp
f010391c:	5b                   	pop    %ebx
f010391d:	5e                   	pop    %esi
f010391e:	5d                   	pop    %ebp
f010391f:	c3                   	ret    

f0103920 <pic_init>:
static bool didinit;

/* Initialize the 8259A interrupt controllers. */
void
pic_init(void)
{
f0103920:	55                   	push   %ebp
f0103921:	89 e5                	mov    %esp,%ebp
f0103923:	83 ec 18             	sub    $0x18,%esp
	didinit = 1;
f0103926:	c7 05 68 f2 2c f0 01 	movl   $0x1,0xf02cf268
f010392d:	00 00 00 
f0103930:	ba 21 00 00 00       	mov    $0x21,%edx
f0103935:	b8 ff ff ff ff       	mov    $0xffffffff,%eax
f010393a:	ee                   	out    %al,(%dx)
f010393b:	b2 a1                	mov    $0xa1,%dl
f010393d:	ee                   	out    %al,(%dx)
f010393e:	b2 20                	mov    $0x20,%dl
f0103940:	b8 11 00 00 00       	mov    $0x11,%eax
f0103945:	ee                   	out    %al,(%dx)
f0103946:	b2 21                	mov    $0x21,%dl
f0103948:	b8 20 00 00 00       	mov    $0x20,%eax
f010394d:	ee                   	out    %al,(%dx)
f010394e:	b8 04 00 00 00       	mov    $0x4,%eax
f0103953:	ee                   	out    %al,(%dx)
f0103954:	b8 03 00 00 00       	mov    $0x3,%eax
f0103959:	ee                   	out    %al,(%dx)
f010395a:	b2 a0                	mov    $0xa0,%dl
f010395c:	b8 11 00 00 00       	mov    $0x11,%eax
f0103961:	ee                   	out    %al,(%dx)
f0103962:	b2 a1                	mov    $0xa1,%dl
f0103964:	b8 28 00 00 00       	mov    $0x28,%eax
f0103969:	ee                   	out    %al,(%dx)
f010396a:	b8 02 00 00 00       	mov    $0x2,%eax
f010396f:	ee                   	out    %al,(%dx)
f0103970:	b8 01 00 00 00       	mov    $0x1,%eax
f0103975:	ee                   	out    %al,(%dx)
f0103976:	b2 20                	mov    $0x20,%dl
f0103978:	b8 68 00 00 00       	mov    $0x68,%eax
f010397d:	ee                   	out    %al,(%dx)
f010397e:	b8 0a 00 00 00       	mov    $0xa,%eax
f0103983:	ee                   	out    %al,(%dx)
f0103984:	b2 a0                	mov    $0xa0,%dl
f0103986:	b8 68 00 00 00       	mov    $0x68,%eax
f010398b:	ee                   	out    %al,(%dx)
f010398c:	b8 0a 00 00 00       	mov    $0xa,%eax
f0103991:	ee                   	out    %al,(%dx)
	outb(IO_PIC1, 0x0a);             /* read IRR by default */

	outb(IO_PIC2, 0x68);               /* OCW3 */
	outb(IO_PIC2, 0x0a);               /* OCW3 */

	if (irq_mask_8259A != 0xFFFF)
f0103992:	0f b7 05 b8 e3 11 f0 	movzwl 0xf011e3b8,%eax
f0103999:	66 83 f8 ff          	cmp    $0xffffffff,%ax
f010399d:	74 0b                	je     f01039aa <pic_init+0x8a>
		irq_setmask_8259A(irq_mask_8259A);
f010399f:	0f b7 c0             	movzwl %ax,%eax
f01039a2:	89 04 24             	mov    %eax,(%esp)
f01039a5:	e8 05 ff ff ff       	call   f01038af <irq_setmask_8259A>
}
f01039aa:	c9                   	leave  
f01039ab:	c3                   	ret    

f01039ac <vcprintf>:
	*cnt++;
}

int
vcprintf(const char *fmt, va_list ap)
{
f01039ac:	55                   	push   %ebp
f01039ad:	89 e5                	mov    %esp,%ebp
f01039af:	83 ec 28             	sub    $0x28,%esp
	int cnt = 0;
f01039b2:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)

	vprintfmt((void*)putch, &cnt, fmt, ap);
f01039b9:	8b 45 0c             	mov    0xc(%ebp),%eax
f01039bc:	89 44 24 0c          	mov    %eax,0xc(%esp)
f01039c0:	8b 45 08             	mov    0x8(%ebp),%eax
f01039c3:	89 44 24 08          	mov    %eax,0x8(%esp)
f01039c7:	8d 45 f4             	lea    -0xc(%ebp),%eax
f01039ca:	89 44 24 04          	mov    %eax,0x4(%esp)
f01039ce:	c7 04 24 f9 39 10 f0 	movl   $0xf01039f9,(%esp)
f01039d5:	e8 63 19 00 00       	call   f010533d <vprintfmt>
	return cnt;
}
f01039da:	8b 45 f4             	mov    -0xc(%ebp),%eax
f01039dd:	c9                   	leave  
f01039de:	c3                   	ret    

f01039df <cprintf>:

int
cprintf(const char *fmt, ...)
{
f01039df:	55                   	push   %ebp
f01039e0:	89 e5                	mov    %esp,%ebp
f01039e2:	83 ec 18             	sub    $0x18,%esp
	vprintfmt((void*)putch, &cnt, fmt, ap);
	return cnt;
}

int
cprintf(const char *fmt, ...)
f01039e5:	8d 45 0c             	lea    0xc(%ebp),%eax
{
	va_list ap;
	int cnt;

	va_start(ap, fmt);
	cnt = vcprintf(fmt, ap);
f01039e8:	89 44 24 04          	mov    %eax,0x4(%esp)
f01039ec:	8b 45 08             	mov    0x8(%ebp),%eax
f01039ef:	89 04 24             	mov    %eax,(%esp)
f01039f2:	e8 b5 ff ff ff       	call   f01039ac <vcprintf>
	va_end(ap);

	return cnt;
}
f01039f7:	c9                   	leave  
f01039f8:	c3                   	ret    

f01039f9 <putch>:
#include <inc/stdarg.h>


static void
putch(int ch, int *cnt)
{
f01039f9:	55                   	push   %ebp
f01039fa:	89 e5                	mov    %esp,%ebp
f01039fc:	83 ec 18             	sub    $0x18,%esp
	cputchar(ch);
f01039ff:	8b 45 08             	mov    0x8(%ebp),%eax
f0103a02:	89 04 24             	mov    %eax,(%esp)
f0103a05:	e8 a4 cc ff ff       	call   f01006ae <cputchar>
	*cnt++;
}
f0103a0a:	c9                   	leave  
f0103a0b:	c3                   	ret    
f0103a0c:	00 00                	add    %al,(%eax)
	...

f0103a10 <idt_init>:
extern void irq47Handler();
extern void syscallHandler();

void
idt_init(void)
{
f0103a10:	55                   	push   %ebp
f0103a11:	89 e5                	mov    %esp,%ebp
	extern struct Segdesc gdt[];
	
	// LAB 3: Your code here.
    SETGATE(idt[T_DIVIDE], 0, GD_KT, divideHandler, 0);
f0103a13:	b8 7c 45 10 f0       	mov    $0xf010457c,%eax
f0103a18:	66 a3 80 f2 2c f0    	mov    %ax,0xf02cf280
f0103a1e:	66 c7 05 82 f2 2c f0 	movw   $0x8,0xf02cf282
f0103a25:	08 00 
f0103a27:	c6 05 84 f2 2c f0 00 	movb   $0x0,0xf02cf284
f0103a2e:	c6 05 85 f2 2c f0 8e 	movb   $0x8e,0xf02cf285
f0103a35:	c1 e8 10             	shr    $0x10,%eax
f0103a38:	66 a3 86 f2 2c f0    	mov    %ax,0xf02cf286
    SETGATE(idt[T_DEBUG], 0, GD_KT, debugHandler, 0);
f0103a3e:	b8 86 45 10 f0       	mov    $0xf0104586,%eax
f0103a43:	66 a3 88 f2 2c f0    	mov    %ax,0xf02cf288
f0103a49:	66 c7 05 8a f2 2c f0 	movw   $0x8,0xf02cf28a
f0103a50:	08 00 
f0103a52:	c6 05 8c f2 2c f0 00 	movb   $0x0,0xf02cf28c
f0103a59:	c6 05 8d f2 2c f0 8e 	movb   $0x8e,0xf02cf28d
f0103a60:	c1 e8 10             	shr    $0x10,%eax
f0103a63:	66 a3 8e f2 2c f0    	mov    %ax,0xf02cf28e
    SETGATE(idt[T_NMI], 0, GD_KT, nmiHandler, 0);
f0103a69:	b8 90 45 10 f0       	mov    $0xf0104590,%eax
f0103a6e:	66 a3 90 f2 2c f0    	mov    %ax,0xf02cf290
f0103a74:	66 c7 05 92 f2 2c f0 	movw   $0x8,0xf02cf292
f0103a7b:	08 00 
f0103a7d:	c6 05 94 f2 2c f0 00 	movb   $0x0,0xf02cf294
f0103a84:	c6 05 95 f2 2c f0 8e 	movb   $0x8e,0xf02cf295
f0103a8b:	c1 e8 10             	shr    $0x10,%eax
f0103a8e:	66 a3 96 f2 2c f0    	mov    %ax,0xf02cf296
    SETGATE(idt[T_BRKPT], 0, GD_KT, brkptHandler, 3);
f0103a94:	b8 9a 45 10 f0       	mov    $0xf010459a,%eax
f0103a99:	66 a3 98 f2 2c f0    	mov    %ax,0xf02cf298
f0103a9f:	66 c7 05 9a f2 2c f0 	movw   $0x8,0xf02cf29a
f0103aa6:	08 00 
f0103aa8:	c6 05 9c f2 2c f0 00 	movb   $0x0,0xf02cf29c
f0103aaf:	c6 05 9d f2 2c f0 ee 	movb   $0xee,0xf02cf29d
f0103ab6:	c1 e8 10             	shr    $0x10,%eax
f0103ab9:	66 a3 9e f2 2c f0    	mov    %ax,0xf02cf29e
    SETGATE(idt[T_OFLOW], 0, GD_KT, oflowHandler, 3);
f0103abf:	b8 a4 45 10 f0       	mov    $0xf01045a4,%eax
f0103ac4:	66 a3 a0 f2 2c f0    	mov    %ax,0xf02cf2a0
f0103aca:	66 c7 05 a2 f2 2c f0 	movw   $0x8,0xf02cf2a2
f0103ad1:	08 00 
f0103ad3:	c6 05 a4 f2 2c f0 00 	movb   $0x0,0xf02cf2a4
f0103ada:	c6 05 a5 f2 2c f0 ee 	movb   $0xee,0xf02cf2a5
f0103ae1:	c1 e8 10             	shr    $0x10,%eax
f0103ae4:	66 a3 a6 f2 2c f0    	mov    %ax,0xf02cf2a6
    SETGATE(idt[T_BOUND], 0, GD_KT, boundHandler, 0);
f0103aea:	b8 ae 45 10 f0       	mov    $0xf01045ae,%eax
f0103aef:	66 a3 a8 f2 2c f0    	mov    %ax,0xf02cf2a8
f0103af5:	66 c7 05 aa f2 2c f0 	movw   $0x8,0xf02cf2aa
f0103afc:	08 00 
f0103afe:	c6 05 ac f2 2c f0 00 	movb   $0x0,0xf02cf2ac
f0103b05:	c6 05 ad f2 2c f0 8e 	movb   $0x8e,0xf02cf2ad
f0103b0c:	c1 e8 10             	shr    $0x10,%eax
f0103b0f:	66 a3 ae f2 2c f0    	mov    %ax,0xf02cf2ae
    SETGATE(idt[T_ILLOP], 0, GD_KT, illopHandler, 0);
f0103b15:	b8 b8 45 10 f0       	mov    $0xf01045b8,%eax
f0103b1a:	66 a3 b0 f2 2c f0    	mov    %ax,0xf02cf2b0
f0103b20:	66 c7 05 b2 f2 2c f0 	movw   $0x8,0xf02cf2b2
f0103b27:	08 00 
f0103b29:	c6 05 b4 f2 2c f0 00 	movb   $0x0,0xf02cf2b4
f0103b30:	c6 05 b5 f2 2c f0 8e 	movb   $0x8e,0xf02cf2b5
f0103b37:	c1 e8 10             	shr    $0x10,%eax
f0103b3a:	66 a3 b6 f2 2c f0    	mov    %ax,0xf02cf2b6
    SETGATE(idt[T_DEVICE], 0, GD_KT, deviceHandler, 0);
f0103b40:	b8 c2 45 10 f0       	mov    $0xf01045c2,%eax
f0103b45:	66 a3 b8 f2 2c f0    	mov    %ax,0xf02cf2b8
f0103b4b:	66 c7 05 ba f2 2c f0 	movw   $0x8,0xf02cf2ba
f0103b52:	08 00 
f0103b54:	c6 05 bc f2 2c f0 00 	movb   $0x0,0xf02cf2bc
f0103b5b:	c6 05 bd f2 2c f0 8e 	movb   $0x8e,0xf02cf2bd
f0103b62:	c1 e8 10             	shr    $0x10,%eax
f0103b65:	66 a3 be f2 2c f0    	mov    %ax,0xf02cf2be
    SETGATE(idt[T_DBLFLT], 0, GD_KT, dblFaultHandler, 0);
f0103b6b:	b8 cc 45 10 f0       	mov    $0xf01045cc,%eax
f0103b70:	66 a3 c0 f2 2c f0    	mov    %ax,0xf02cf2c0
f0103b76:	66 c7 05 c2 f2 2c f0 	movw   $0x8,0xf02cf2c2
f0103b7d:	08 00 
f0103b7f:	c6 05 c4 f2 2c f0 00 	movb   $0x0,0xf02cf2c4
f0103b86:	c6 05 c5 f2 2c f0 8e 	movb   $0x8e,0xf02cf2c5
f0103b8d:	c1 e8 10             	shr    $0x10,%eax
f0103b90:	66 a3 c6 f2 2c f0    	mov    %ax,0xf02cf2c6

    SETGATE(idt[T_TSS], 0, GD_KT, tssHandler, 0);
f0103b96:	b8 d4 45 10 f0       	mov    $0xf01045d4,%eax
f0103b9b:	66 a3 d0 f2 2c f0    	mov    %ax,0xf02cf2d0
f0103ba1:	66 c7 05 d2 f2 2c f0 	movw   $0x8,0xf02cf2d2
f0103ba8:	08 00 
f0103baa:	c6 05 d4 f2 2c f0 00 	movb   $0x0,0xf02cf2d4
f0103bb1:	c6 05 d5 f2 2c f0 8e 	movb   $0x8e,0xf02cf2d5
f0103bb8:	c1 e8 10             	shr    $0x10,%eax
f0103bbb:	66 a3 d6 f2 2c f0    	mov    %ax,0xf02cf2d6
    SETGATE(idt[T_SEGNP], 0, GD_KT, segnpHandler, 0);
f0103bc1:	b8 dc 45 10 f0       	mov    $0xf01045dc,%eax
f0103bc6:	66 a3 d8 f2 2c f0    	mov    %ax,0xf02cf2d8
f0103bcc:	66 c7 05 da f2 2c f0 	movw   $0x8,0xf02cf2da
f0103bd3:	08 00 
f0103bd5:	c6 05 dc f2 2c f0 00 	movb   $0x0,0xf02cf2dc
f0103bdc:	c6 05 dd f2 2c f0 8e 	movb   $0x8e,0xf02cf2dd
f0103be3:	c1 e8 10             	shr    $0x10,%eax
f0103be6:	66 a3 de f2 2c f0    	mov    %ax,0xf02cf2de
    SETGATE(idt[T_STACK], 0, GD_KT, stackHandler, 0);
f0103bec:	b8 e4 45 10 f0       	mov    $0xf01045e4,%eax
f0103bf1:	66 a3 e0 f2 2c f0    	mov    %ax,0xf02cf2e0
f0103bf7:	66 c7 05 e2 f2 2c f0 	movw   $0x8,0xf02cf2e2
f0103bfe:	08 00 
f0103c00:	c6 05 e4 f2 2c f0 00 	movb   $0x0,0xf02cf2e4
f0103c07:	c6 05 e5 f2 2c f0 8e 	movb   $0x8e,0xf02cf2e5
f0103c0e:	c1 e8 10             	shr    $0x10,%eax
f0103c11:	66 a3 e6 f2 2c f0    	mov    %ax,0xf02cf2e6
    SETGATE(idt[T_GPFLT], 0, GD_KT, gpfltHandler, 0);
f0103c17:	b8 ec 45 10 f0       	mov    $0xf01045ec,%eax
f0103c1c:	66 a3 e8 f2 2c f0    	mov    %ax,0xf02cf2e8
f0103c22:	66 c7 05 ea f2 2c f0 	movw   $0x8,0xf02cf2ea
f0103c29:	08 00 
f0103c2b:	c6 05 ec f2 2c f0 00 	movb   $0x0,0xf02cf2ec
f0103c32:	c6 05 ed f2 2c f0 8e 	movb   $0x8e,0xf02cf2ed
f0103c39:	c1 e8 10             	shr    $0x10,%eax
f0103c3c:	66 a3 ee f2 2c f0    	mov    %ax,0xf02cf2ee
    SETGATE(idt[T_PGFLT], 0, GD_KT, pgfltHandler, 0);
f0103c42:	b8 f4 45 10 f0       	mov    $0xf01045f4,%eax
f0103c47:	66 a3 f0 f2 2c f0    	mov    %ax,0xf02cf2f0
f0103c4d:	66 c7 05 f2 f2 2c f0 	movw   $0x8,0xf02cf2f2
f0103c54:	08 00 
f0103c56:	c6 05 f4 f2 2c f0 00 	movb   $0x0,0xf02cf2f4
f0103c5d:	c6 05 f5 f2 2c f0 8e 	movb   $0x8e,0xf02cf2f5
f0103c64:	c1 e8 10             	shr    $0x10,%eax
f0103c67:	66 a3 f6 f2 2c f0    	mov    %ax,0xf02cf2f6

    SETGATE(idt[T_FPERR], 0, GD_KT, fperrHandler, 0);
f0103c6d:	b8 f8 45 10 f0       	mov    $0xf01045f8,%eax
f0103c72:	66 a3 00 f3 2c f0    	mov    %ax,0xf02cf300
f0103c78:	66 c7 05 02 f3 2c f0 	movw   $0x8,0xf02cf302
f0103c7f:	08 00 
f0103c81:	c6 05 04 f3 2c f0 00 	movb   $0x0,0xf02cf304
f0103c88:	c6 05 05 f3 2c f0 8e 	movb   $0x8e,0xf02cf305
f0103c8f:	c1 e8 10             	shr    $0x10,%eax
f0103c92:	66 a3 06 f3 2c f0    	mov    %ax,0xf02cf306
    SETGATE(idt[T_ALIGN], 0, GD_KT, alignHandler, 0);
f0103c98:	b8 fe 45 10 f0       	mov    $0xf01045fe,%eax
f0103c9d:	66 a3 08 f3 2c f0    	mov    %ax,0xf02cf308
f0103ca3:	66 c7 05 0a f3 2c f0 	movw   $0x8,0xf02cf30a
f0103caa:	08 00 
f0103cac:	c6 05 0c f3 2c f0 00 	movb   $0x0,0xf02cf30c
f0103cb3:	c6 05 0d f3 2c f0 8e 	movb   $0x8e,0xf02cf30d
f0103cba:	c1 e8 10             	shr    $0x10,%eax
f0103cbd:	66 a3 0e f3 2c f0    	mov    %ax,0xf02cf30e
    SETGATE(idt[T_MCHK], 0, GD_KT, mchkHandler, 0);
f0103cc3:	b8 02 46 10 f0       	mov    $0xf0104602,%eax
f0103cc8:	66 a3 10 f3 2c f0    	mov    %ax,0xf02cf310
f0103cce:	66 c7 05 12 f3 2c f0 	movw   $0x8,0xf02cf312
f0103cd5:	08 00 
f0103cd7:	c6 05 14 f3 2c f0 00 	movb   $0x0,0xf02cf314
f0103cde:	c6 05 15 f3 2c f0 8e 	movb   $0x8e,0xf02cf315
f0103ce5:	c1 e8 10             	shr    $0x10,%eax
f0103ce8:	66 a3 16 f3 2c f0    	mov    %ax,0xf02cf316
    SETGATE(idt[T_SIMDERR], 0, GD_KT, simderrHandler, 0);
f0103cee:	b8 08 46 10 f0       	mov    $0xf0104608,%eax
f0103cf3:	66 a3 18 f3 2c f0    	mov    %ax,0xf02cf318
f0103cf9:	66 c7 05 1a f3 2c f0 	movw   $0x8,0xf02cf31a
f0103d00:	08 00 
f0103d02:	c6 05 1c f3 2c f0 00 	movb   $0x0,0xf02cf31c
f0103d09:	c6 05 1d f3 2c f0 8e 	movb   $0x8e,0xf02cf31d
f0103d10:	c1 e8 10             	shr    $0x10,%eax
f0103d13:	66 a3 1e f3 2c f0    	mov    %ax,0xf02cf31e

    // Device IRQs

    SETGATE(idt[32], 0, GD_KT, irq32Handler, 0);
f0103d19:	b8 0e 46 10 f0       	mov    $0xf010460e,%eax
f0103d1e:	66 a3 80 f3 2c f0    	mov    %ax,0xf02cf380
f0103d24:	66 c7 05 82 f3 2c f0 	movw   $0x8,0xf02cf382
f0103d2b:	08 00 
f0103d2d:	c6 05 84 f3 2c f0 00 	movb   $0x0,0xf02cf384
f0103d34:	c6 05 85 f3 2c f0 8e 	movb   $0x8e,0xf02cf385
f0103d3b:	c1 e8 10             	shr    $0x10,%eax
f0103d3e:	66 a3 86 f3 2c f0    	mov    %ax,0xf02cf386
    SETGATE(idt[33], 0, GD_KT, irq33Handler, 0);
f0103d44:	b8 14 46 10 f0       	mov    $0xf0104614,%eax
f0103d49:	66 a3 88 f3 2c f0    	mov    %ax,0xf02cf388
f0103d4f:	66 c7 05 8a f3 2c f0 	movw   $0x8,0xf02cf38a
f0103d56:	08 00 
f0103d58:	c6 05 8c f3 2c f0 00 	movb   $0x0,0xf02cf38c
f0103d5f:	c6 05 8d f3 2c f0 8e 	movb   $0x8e,0xf02cf38d
f0103d66:	c1 e8 10             	shr    $0x10,%eax
f0103d69:	66 a3 8e f3 2c f0    	mov    %ax,0xf02cf38e
    SETGATE(idt[34], 0, GD_KT, irq34Handler, 0);
f0103d6f:	b8 1a 46 10 f0       	mov    $0xf010461a,%eax
f0103d74:	66 a3 90 f3 2c f0    	mov    %ax,0xf02cf390
f0103d7a:	66 c7 05 92 f3 2c f0 	movw   $0x8,0xf02cf392
f0103d81:	08 00 
f0103d83:	c6 05 94 f3 2c f0 00 	movb   $0x0,0xf02cf394
f0103d8a:	c6 05 95 f3 2c f0 8e 	movb   $0x8e,0xf02cf395
f0103d91:	c1 e8 10             	shr    $0x10,%eax
f0103d94:	66 a3 96 f3 2c f0    	mov    %ax,0xf02cf396
    SETGATE(idt[35], 0, GD_KT, irq35Handler, 0);
f0103d9a:	b8 20 46 10 f0       	mov    $0xf0104620,%eax
f0103d9f:	66 a3 98 f3 2c f0    	mov    %ax,0xf02cf398
f0103da5:	66 c7 05 9a f3 2c f0 	movw   $0x8,0xf02cf39a
f0103dac:	08 00 
f0103dae:	c6 05 9c f3 2c f0 00 	movb   $0x0,0xf02cf39c
f0103db5:	c6 05 9d f3 2c f0 8e 	movb   $0x8e,0xf02cf39d
f0103dbc:	c1 e8 10             	shr    $0x10,%eax
f0103dbf:	66 a3 9e f3 2c f0    	mov    %ax,0xf02cf39e
    SETGATE(idt[36], 0, GD_KT, irq36Handler, 0);
f0103dc5:	b8 26 46 10 f0       	mov    $0xf0104626,%eax
f0103dca:	66 a3 a0 f3 2c f0    	mov    %ax,0xf02cf3a0
f0103dd0:	66 c7 05 a2 f3 2c f0 	movw   $0x8,0xf02cf3a2
f0103dd7:	08 00 
f0103dd9:	c6 05 a4 f3 2c f0 00 	movb   $0x0,0xf02cf3a4
f0103de0:	c6 05 a5 f3 2c f0 8e 	movb   $0x8e,0xf02cf3a5
f0103de7:	c1 e8 10             	shr    $0x10,%eax
f0103dea:	66 a3 a6 f3 2c f0    	mov    %ax,0xf02cf3a6
    SETGATE(idt[37], 0, GD_KT, irq37Handler, 0);
f0103df0:	b8 2c 46 10 f0       	mov    $0xf010462c,%eax
f0103df5:	66 a3 a8 f3 2c f0    	mov    %ax,0xf02cf3a8
f0103dfb:	66 c7 05 aa f3 2c f0 	movw   $0x8,0xf02cf3aa
f0103e02:	08 00 
f0103e04:	c6 05 ac f3 2c f0 00 	movb   $0x0,0xf02cf3ac
f0103e0b:	c6 05 ad f3 2c f0 8e 	movb   $0x8e,0xf02cf3ad
f0103e12:	c1 e8 10             	shr    $0x10,%eax
f0103e15:	66 a3 ae f3 2c f0    	mov    %ax,0xf02cf3ae
    SETGATE(idt[38], 0, GD_KT, irq38Handler, 0);
f0103e1b:	b8 32 46 10 f0       	mov    $0xf0104632,%eax
f0103e20:	66 a3 b0 f3 2c f0    	mov    %ax,0xf02cf3b0
f0103e26:	66 c7 05 b2 f3 2c f0 	movw   $0x8,0xf02cf3b2
f0103e2d:	08 00 
f0103e2f:	c6 05 b4 f3 2c f0 00 	movb   $0x0,0xf02cf3b4
f0103e36:	c6 05 b5 f3 2c f0 8e 	movb   $0x8e,0xf02cf3b5
f0103e3d:	c1 e8 10             	shr    $0x10,%eax
f0103e40:	66 a3 b6 f3 2c f0    	mov    %ax,0xf02cf3b6
    SETGATE(idt[39], 0, GD_KT, irq39Handler, 0);
f0103e46:	b8 38 46 10 f0       	mov    $0xf0104638,%eax
f0103e4b:	66 a3 b8 f3 2c f0    	mov    %ax,0xf02cf3b8
f0103e51:	66 c7 05 ba f3 2c f0 	movw   $0x8,0xf02cf3ba
f0103e58:	08 00 
f0103e5a:	c6 05 bc f3 2c f0 00 	movb   $0x0,0xf02cf3bc
f0103e61:	c6 05 bd f3 2c f0 8e 	movb   $0x8e,0xf02cf3bd
f0103e68:	c1 e8 10             	shr    $0x10,%eax
f0103e6b:	66 a3 be f3 2c f0    	mov    %ax,0xf02cf3be
    SETGATE(idt[40], 0, GD_KT, irq40Handler, 0);
f0103e71:	b8 3e 46 10 f0       	mov    $0xf010463e,%eax
f0103e76:	66 a3 c0 f3 2c f0    	mov    %ax,0xf02cf3c0
f0103e7c:	66 c7 05 c2 f3 2c f0 	movw   $0x8,0xf02cf3c2
f0103e83:	08 00 
f0103e85:	c6 05 c4 f3 2c f0 00 	movb   $0x0,0xf02cf3c4
f0103e8c:	c6 05 c5 f3 2c f0 8e 	movb   $0x8e,0xf02cf3c5
f0103e93:	c1 e8 10             	shr    $0x10,%eax
f0103e96:	66 a3 c6 f3 2c f0    	mov    %ax,0xf02cf3c6
    SETGATE(idt[41], 0, GD_KT, irq41Handler, 0);
f0103e9c:	b8 44 46 10 f0       	mov    $0xf0104644,%eax
f0103ea1:	66 a3 c8 f3 2c f0    	mov    %ax,0xf02cf3c8
f0103ea7:	66 c7 05 ca f3 2c f0 	movw   $0x8,0xf02cf3ca
f0103eae:	08 00 
f0103eb0:	c6 05 cc f3 2c f0 00 	movb   $0x0,0xf02cf3cc
f0103eb7:	c6 05 cd f3 2c f0 8e 	movb   $0x8e,0xf02cf3cd
f0103ebe:	c1 e8 10             	shr    $0x10,%eax
f0103ec1:	66 a3 ce f3 2c f0    	mov    %ax,0xf02cf3ce
    SETGATE(idt[42], 0, GD_KT, irq42Handler, 0);
f0103ec7:	b8 4a 46 10 f0       	mov    $0xf010464a,%eax
f0103ecc:	66 a3 d0 f3 2c f0    	mov    %ax,0xf02cf3d0
f0103ed2:	66 c7 05 d2 f3 2c f0 	movw   $0x8,0xf02cf3d2
f0103ed9:	08 00 
f0103edb:	c6 05 d4 f3 2c f0 00 	movb   $0x0,0xf02cf3d4
f0103ee2:	c6 05 d5 f3 2c f0 8e 	movb   $0x8e,0xf02cf3d5
f0103ee9:	c1 e8 10             	shr    $0x10,%eax
f0103eec:	66 a3 d6 f3 2c f0    	mov    %ax,0xf02cf3d6
    SETGATE(idt[43], 0, GD_KT, irq43Handler, 0);
f0103ef2:	b8 50 46 10 f0       	mov    $0xf0104650,%eax
f0103ef7:	66 a3 d8 f3 2c f0    	mov    %ax,0xf02cf3d8
f0103efd:	66 c7 05 da f3 2c f0 	movw   $0x8,0xf02cf3da
f0103f04:	08 00 
f0103f06:	c6 05 dc f3 2c f0 00 	movb   $0x0,0xf02cf3dc
f0103f0d:	c6 05 dd f3 2c f0 8e 	movb   $0x8e,0xf02cf3dd
f0103f14:	c1 e8 10             	shr    $0x10,%eax
f0103f17:	66 a3 de f3 2c f0    	mov    %ax,0xf02cf3de
    SETGATE(idt[44], 0, GD_KT, irq44Handler, 0);
f0103f1d:	b8 56 46 10 f0       	mov    $0xf0104656,%eax
f0103f22:	66 a3 e0 f3 2c f0    	mov    %ax,0xf02cf3e0
f0103f28:	66 c7 05 e2 f3 2c f0 	movw   $0x8,0xf02cf3e2
f0103f2f:	08 00 
f0103f31:	c6 05 e4 f3 2c f0 00 	movb   $0x0,0xf02cf3e4
f0103f38:	c6 05 e5 f3 2c f0 8e 	movb   $0x8e,0xf02cf3e5
f0103f3f:	c1 e8 10             	shr    $0x10,%eax
f0103f42:	66 a3 e6 f3 2c f0    	mov    %ax,0xf02cf3e6
    SETGATE(idt[45], 0, GD_KT, irq45Handler, 0);
f0103f48:	b8 5c 46 10 f0       	mov    $0xf010465c,%eax
f0103f4d:	66 a3 e8 f3 2c f0    	mov    %ax,0xf02cf3e8
f0103f53:	66 c7 05 ea f3 2c f0 	movw   $0x8,0xf02cf3ea
f0103f5a:	08 00 
f0103f5c:	c6 05 ec f3 2c f0 00 	movb   $0x0,0xf02cf3ec
f0103f63:	c6 05 ed f3 2c f0 8e 	movb   $0x8e,0xf02cf3ed
f0103f6a:	c1 e8 10             	shr    $0x10,%eax
f0103f6d:	66 a3 ee f3 2c f0    	mov    %ax,0xf02cf3ee
    SETGATE(idt[46], 0, GD_KT, irq46Handler, 0);
f0103f73:	b8 62 46 10 f0       	mov    $0xf0104662,%eax
f0103f78:	66 a3 f0 f3 2c f0    	mov    %ax,0xf02cf3f0
f0103f7e:	66 c7 05 f2 f3 2c f0 	movw   $0x8,0xf02cf3f2
f0103f85:	08 00 
f0103f87:	c6 05 f4 f3 2c f0 00 	movb   $0x0,0xf02cf3f4
f0103f8e:	c6 05 f5 f3 2c f0 8e 	movb   $0x8e,0xf02cf3f5
f0103f95:	c1 e8 10             	shr    $0x10,%eax
f0103f98:	66 a3 f6 f3 2c f0    	mov    %ax,0xf02cf3f6
    SETGATE(idt[47], 0, GD_KT, irq47Handler, 0);
f0103f9e:	b8 68 46 10 f0       	mov    $0xf0104668,%eax
f0103fa3:	66 a3 f8 f3 2c f0    	mov    %ax,0xf02cf3f8
f0103fa9:	66 c7 05 fa f3 2c f0 	movw   $0x8,0xf02cf3fa
f0103fb0:	08 00 
f0103fb2:	c6 05 fc f3 2c f0 00 	movb   $0x0,0xf02cf3fc
f0103fb9:	c6 05 fd f3 2c f0 8e 	movb   $0x8e,0xf02cf3fd
f0103fc0:	c1 e8 10             	shr    $0x10,%eax
f0103fc3:	66 a3 fe f3 2c f0    	mov    %ax,0xf02cf3fe

    SETGATE(idt[T_SYSCALL], 0, GD_KT, syscallHandler, 3);
f0103fc9:	b8 6e 46 10 f0       	mov    $0xf010466e,%eax
f0103fce:	66 a3 00 f4 2c f0    	mov    %ax,0xf02cf400
f0103fd4:	66 c7 05 02 f4 2c f0 	movw   $0x8,0xf02cf402
f0103fdb:	08 00 
f0103fdd:	c6 05 04 f4 2c f0 00 	movb   $0x0,0xf02cf404
f0103fe4:	c6 05 05 f4 2c f0 ee 	movb   $0xee,0xf02cf405
f0103feb:	c1 e8 10             	shr    $0x10,%eax
f0103fee:	66 a3 06 f4 2c f0    	mov    %ax,0xf02cf406

	// Setup a TSS so that we get the right stack
	// when we trap to the kernel.
	ts.ts_esp0    = KSTACKTOP;
f0103ff4:	c7 05 84 fa 2c f0 00 	movl   $0xefc00000,0xf02cfa84
f0103ffb:	00 c0 ef 
	ts.ts_ss0     = GD_KD;
f0103ffe:	66 c7 05 88 fa 2c f0 	movw   $0x10,0xf02cfa88
f0104005:	10 00 

	// Initialize the TSS field of the gdt.
	gdt[GD_TSS >> 3] = SEG16(STS_T32A, (uint32_t) (&ts),
f0104007:	66 c7 05 a8 e3 11 f0 	movw   $0x68,0xf011e3a8
f010400e:	68 00 
f0104010:	b8 80 fa 2c f0       	mov    $0xf02cfa80,%eax
f0104015:	66 a3 aa e3 11 f0    	mov    %ax,0xf011e3aa
f010401b:	89 c2                	mov    %eax,%edx
f010401d:	c1 ea 10             	shr    $0x10,%edx
f0104020:	88 15 ac e3 11 f0    	mov    %dl,0xf011e3ac
f0104026:	c6 05 ae e3 11 f0 40 	movb   $0x40,0xf011e3ae
f010402d:	c1 e8 18             	shr    $0x18,%eax
f0104030:	a2 af e3 11 f0       	mov    %al,0xf011e3af
					sizeof(struct Taskstate), 0);
	gdt[GD_TSS >> 3].sd_s = 0;
f0104035:	c6 05 ad e3 11 f0 89 	movb   $0x89,0xf011e3ad
}

static __inline void
ltr(uint16_t sel)
{
	__asm __volatile("ltr %0" : : "r" (sel));
f010403c:	b8 28 00 00 00       	mov    $0x28,%eax
f0104041:	0f 00 d8             	ltr    %ax

	// Load the TSS
	ltr(GD_TSS);

	// Load the IDT
	asm volatile("lidt idt_pd");
f0104044:	0f 01 1d bc e3 11 f0 	lidtl  0xf011e3bc
}
f010404b:	5d                   	pop    %ebp
f010404c:	c3                   	ret    

f010404d <debug_handler>:
  }
  return;
}

void
debug_handler(struct Trapframe *tf) {
f010404d:	55                   	push   %ebp
f010404e:	89 e5                	mov    %esp,%ebp
f0104050:	83 ec 18             	sub    $0x18,%esp
  monitor(tf);
f0104053:	8b 45 08             	mov    0x8(%ebp),%eax
f0104056:	89 04 24             	mov    %eax,(%esp)
f0104059:	e8 92 c9 ff ff       	call   f01009f0 <monitor>
}
f010405e:	c9                   	leave  
f010405f:	c3                   	ret    

f0104060 <break_point_handler>:
	print_trapframe(tf);
	env_destroy(curenv);
}

void
break_point_handler(struct Trapframe *tf) {
f0104060:	55                   	push   %ebp
f0104061:	89 e5                	mov    %esp,%ebp
f0104063:	83 ec 18             	sub    $0x18,%esp
  monitor(tf);
f0104066:	8b 45 08             	mov    0x8(%ebp),%eax
f0104069:	89 04 24             	mov    %eax,(%esp)
f010406c:	e8 7f c9 ff ff       	call   f01009f0 <monitor>
}
f0104071:	c9                   	leave  
f0104072:	c3                   	ret    

f0104073 <print_regs>:
	cprintf("  ss   0x----%04x\n", tf->tf_ss);
}

void
print_regs(struct PushRegs *regs)
{
f0104073:	55                   	push   %ebp
f0104074:	89 e5                	mov    %esp,%ebp
f0104076:	53                   	push   %ebx
f0104077:	83 ec 14             	sub    $0x14,%esp
f010407a:	8b 5d 08             	mov    0x8(%ebp),%ebx
	cprintf("  edi  0x%08x\n", regs->reg_edi);
f010407d:	8b 03                	mov    (%ebx),%eax
f010407f:	89 44 24 04          	mov    %eax,0x4(%esp)
f0104083:	c7 04 24 1e 79 10 f0 	movl   $0xf010791e,(%esp)
f010408a:	e8 50 f9 ff ff       	call   f01039df <cprintf>
	cprintf("  esi  0x%08x\n", regs->reg_esi);
f010408f:	8b 43 04             	mov    0x4(%ebx),%eax
f0104092:	89 44 24 04          	mov    %eax,0x4(%esp)
f0104096:	c7 04 24 2d 79 10 f0 	movl   $0xf010792d,(%esp)
f010409d:	e8 3d f9 ff ff       	call   f01039df <cprintf>
	cprintf("  ebp  0x%08x\n", regs->reg_ebp);
f01040a2:	8b 43 08             	mov    0x8(%ebx),%eax
f01040a5:	89 44 24 04          	mov    %eax,0x4(%esp)
f01040a9:	c7 04 24 3c 79 10 f0 	movl   $0xf010793c,(%esp)
f01040b0:	e8 2a f9 ff ff       	call   f01039df <cprintf>
	cprintf("  oesp 0x%08x\n", regs->reg_oesp);
f01040b5:	8b 43 0c             	mov    0xc(%ebx),%eax
f01040b8:	89 44 24 04          	mov    %eax,0x4(%esp)
f01040bc:	c7 04 24 4b 79 10 f0 	movl   $0xf010794b,(%esp)
f01040c3:	e8 17 f9 ff ff       	call   f01039df <cprintf>
	cprintf("  ebx  0x%08x\n", regs->reg_ebx);
f01040c8:	8b 43 10             	mov    0x10(%ebx),%eax
f01040cb:	89 44 24 04          	mov    %eax,0x4(%esp)
f01040cf:	c7 04 24 5a 79 10 f0 	movl   $0xf010795a,(%esp)
f01040d6:	e8 04 f9 ff ff       	call   f01039df <cprintf>
	cprintf("  edx  0x%08x\n", regs->reg_edx);
f01040db:	8b 43 14             	mov    0x14(%ebx),%eax
f01040de:	89 44 24 04          	mov    %eax,0x4(%esp)
f01040e2:	c7 04 24 69 79 10 f0 	movl   $0xf0107969,(%esp)
f01040e9:	e8 f1 f8 ff ff       	call   f01039df <cprintf>
	cprintf("  ecx  0x%08x\n", regs->reg_ecx);
f01040ee:	8b 43 18             	mov    0x18(%ebx),%eax
f01040f1:	89 44 24 04          	mov    %eax,0x4(%esp)
f01040f5:	c7 04 24 78 79 10 f0 	movl   $0xf0107978,(%esp)
f01040fc:	e8 de f8 ff ff       	call   f01039df <cprintf>
	cprintf("  eax  0x%08x\n", regs->reg_eax);
f0104101:	8b 43 1c             	mov    0x1c(%ebx),%eax
f0104104:	89 44 24 04          	mov    %eax,0x4(%esp)
f0104108:	c7 04 24 87 79 10 f0 	movl   $0xf0107987,(%esp)
f010410f:	e8 cb f8 ff ff       	call   f01039df <cprintf>
}
f0104114:	83 c4 14             	add    $0x14,%esp
f0104117:	5b                   	pop    %ebx
f0104118:	5d                   	pop    %ebp
f0104119:	c3                   	ret    

f010411a <print_trapframe>:
	asm volatile("lidt idt_pd");
}

void
print_trapframe(struct Trapframe *tf)
{
f010411a:	55                   	push   %ebp
f010411b:	89 e5                	mov    %esp,%ebp
f010411d:	53                   	push   %ebx
f010411e:	83 ec 14             	sub    $0x14,%esp
f0104121:	8b 5d 08             	mov    0x8(%ebp),%ebx
	cprintf("TRAP frame at %p\n", tf);
f0104124:	89 5c 24 04          	mov    %ebx,0x4(%esp)
f0104128:	c7 04 24 96 79 10 f0 	movl   $0xf0107996,(%esp)
f010412f:	e8 ab f8 ff ff       	call   f01039df <cprintf>
	print_regs(&tf->tf_regs);
f0104134:	89 1c 24             	mov    %ebx,(%esp)
f0104137:	e8 37 ff ff ff       	call   f0104073 <print_regs>
	cprintf("  es   0x----%04x\n", tf->tf_es);
f010413c:	0f b7 43 20          	movzwl 0x20(%ebx),%eax
f0104140:	89 44 24 04          	mov    %eax,0x4(%esp)
f0104144:	c7 04 24 a8 79 10 f0 	movl   $0xf01079a8,(%esp)
f010414b:	e8 8f f8 ff ff       	call   f01039df <cprintf>
	cprintf("  ds   0x----%04x\n", tf->tf_ds);
f0104150:	0f b7 43 24          	movzwl 0x24(%ebx),%eax
f0104154:	89 44 24 04          	mov    %eax,0x4(%esp)
f0104158:	c7 04 24 bb 79 10 f0 	movl   $0xf01079bb,(%esp)
f010415f:	e8 7b f8 ff ff       	call   f01039df <cprintf>
	cprintf("  trap 0x%08x %s\n", tf->tf_trapno, trapname(tf->tf_trapno));
f0104164:	8b 43 28             	mov    0x28(%ebx),%eax
		"Alignment Check",
		"Machine-Check",
		"SIMD Floating-Point Exception"
	};

	if (trapno < sizeof(excnames)/sizeof(excnames[0]))
f0104167:	83 f8 13             	cmp    $0x13,%eax
f010416a:	77 09                	ja     f0104175 <print_trapframe+0x5b>
		return excnames[trapno];
f010416c:	8b 14 85 60 7d 10 f0 	mov    -0xfef82a0(,%eax,4),%edx
f0104173:	eb 1d                	jmp    f0104192 <print_trapframe+0x78>
	if (trapno == T_SYSCALL)
f0104175:	ba ce 79 10 f0       	mov    $0xf01079ce,%edx
f010417a:	83 f8 30             	cmp    $0x30,%eax
f010417d:	74 13                	je     f0104192 <print_trapframe+0x78>
		return "System call";
	if (trapno >= IRQ_OFFSET && trapno < IRQ_OFFSET + 16)
f010417f:	8d 50 e0             	lea    -0x20(%eax),%edx
f0104182:	83 fa 10             	cmp    $0x10,%edx
f0104185:	ba da 79 10 f0       	mov    $0xf01079da,%edx
f010418a:	b9 e9 79 10 f0       	mov    $0xf01079e9,%ecx
f010418f:	0f 42 d1             	cmovb  %ecx,%edx
{
	cprintf("TRAP frame at %p\n", tf);
	print_regs(&tf->tf_regs);
	cprintf("  es   0x----%04x\n", tf->tf_es);
	cprintf("  ds   0x----%04x\n", tf->tf_ds);
	cprintf("  trap 0x%08x %s\n", tf->tf_trapno, trapname(tf->tf_trapno));
f0104192:	89 54 24 08          	mov    %edx,0x8(%esp)
f0104196:	89 44 24 04          	mov    %eax,0x4(%esp)
f010419a:	c7 04 24 fc 79 10 f0 	movl   $0xf01079fc,(%esp)
f01041a1:	e8 39 f8 ff ff       	call   f01039df <cprintf>
	cprintf("  err  0x%08x\n", tf->tf_err);
f01041a6:	8b 43 2c             	mov    0x2c(%ebx),%eax
f01041a9:	89 44 24 04          	mov    %eax,0x4(%esp)
f01041ad:	c7 04 24 0e 7a 10 f0 	movl   $0xf0107a0e,(%esp)
f01041b4:	e8 26 f8 ff ff       	call   f01039df <cprintf>
	cprintf("  eip  0x%08x\n", tf->tf_eip);
f01041b9:	8b 43 30             	mov    0x30(%ebx),%eax
f01041bc:	89 44 24 04          	mov    %eax,0x4(%esp)
f01041c0:	c7 04 24 1d 7a 10 f0 	movl   $0xf0107a1d,(%esp)
f01041c7:	e8 13 f8 ff ff       	call   f01039df <cprintf>
	cprintf("  cs   0x----%04x\n", tf->tf_cs);
f01041cc:	0f b7 43 34          	movzwl 0x34(%ebx),%eax
f01041d0:	89 44 24 04          	mov    %eax,0x4(%esp)
f01041d4:	c7 04 24 2c 7a 10 f0 	movl   $0xf0107a2c,(%esp)
f01041db:	e8 ff f7 ff ff       	call   f01039df <cprintf>
	cprintf("  flag 0x%08x\n", tf->tf_eflags);
f01041e0:	8b 43 38             	mov    0x38(%ebx),%eax
f01041e3:	89 44 24 04          	mov    %eax,0x4(%esp)
f01041e7:	c7 04 24 3f 7a 10 f0 	movl   $0xf0107a3f,(%esp)
f01041ee:	e8 ec f7 ff ff       	call   f01039df <cprintf>
	cprintf("  esp  0x%08x\n", tf->tf_esp);
f01041f3:	8b 43 3c             	mov    0x3c(%ebx),%eax
f01041f6:	89 44 24 04          	mov    %eax,0x4(%esp)
f01041fa:	c7 04 24 4e 7a 10 f0 	movl   $0xf0107a4e,(%esp)
f0104201:	e8 d9 f7 ff ff       	call   f01039df <cprintf>
	cprintf("  ss   0x----%04x\n", tf->tf_ss);
f0104206:	0f b7 43 40          	movzwl 0x40(%ebx),%eax
f010420a:	89 44 24 04          	mov    %eax,0x4(%esp)
f010420e:	c7 04 24 5d 7a 10 f0 	movl   $0xf0107a5d,(%esp)
f0104215:	e8 c5 f7 ff ff       	call   f01039df <cprintf>
}
f010421a:	83 c4 14             	add    $0x14,%esp
f010421d:	5b                   	pop    %ebx
f010421e:	5d                   	pop    %ebp
f010421f:	c3                   	ret    

f0104220 <syscall_handler>:
break_point_handler(struct Trapframe *tf) {
  monitor(tf);
}

void
syscall_handler(struct Trapframe *tf) {
f0104220:	55                   	push   %ebp
f0104221:	89 e5                	mov    %esp,%ebp
f0104223:	83 ec 28             	sub    $0x28,%esp
f0104226:	89 75 f8             	mov    %esi,-0x8(%ebp)
f0104229:	89 7d fc             	mov    %edi,-0x4(%ebp)
f010422c:	8b 45 08             	mov    0x8(%ebp),%eax
  if (tf->tf_cs == GD_KT) {
f010422f:	0f b7 50 34          	movzwl 0x34(%eax),%edx
f0104233:	66 83 fa 08          	cmp    $0x8,%dx
f0104237:	75 24                	jne    f010425d <syscall_handler+0x3d>
    print_trapframe(tf);
f0104239:	89 04 24             	mov    %eax,(%esp)
f010423c:	e8 d9 fe ff ff       	call   f010411a <print_trapframe>
    panic("Syscall in Kernel Mode\n");
f0104241:	c7 44 24 08 70 7a 10 	movl   $0xf0107a70,0x8(%esp)
f0104248:	f0 
f0104249:	c7 44 24 04 87 01 00 	movl   $0x187,0x4(%esp)
f0104250:	00 
f0104251:	c7 04 24 88 7a 10 f0 	movl   $0xf0107a88,(%esp)
f0104258:	e8 28 be ff ff       	call   f0100085 <_panic>
    return;
  }
  
  //Check if syscall is invoked from user mode.
  if ((tf->tf_cs&(~0x3)) == GD_UT) {
f010425d:	81 e2 fc ff 00 00    	and    $0xfffc,%edx
f0104263:	83 fa 18             	cmp    $0x18,%edx
f0104266:	75 47                	jne    f01042af <syscall_handler+0x8f>
    curenv->env_tf  = *tf;
f0104268:	8b 15 60 f2 2c f0    	mov    0xf02cf260,%edx
f010426e:	b9 11 00 00 00       	mov    $0x11,%ecx
f0104273:	89 d7                	mov    %edx,%edi
f0104275:	89 c6                	mov    %eax,%esi
f0104277:	f3 a5                	rep movsl %ds:(%esi),%es:(%edi)
    curenv->env_tf.tf_regs.reg_eax = syscall(tf->tf_regs.reg_eax, tf->tf_regs.reg_edx, tf->tf_regs.reg_ecx, tf->tf_regs.reg_ebx, tf->tf_regs.reg_edi, tf->tf_regs.reg_esi);
f0104279:	8b 35 60 f2 2c f0    	mov    0xf02cf260,%esi
f010427f:	8b 50 04             	mov    0x4(%eax),%edx
f0104282:	89 54 24 14          	mov    %edx,0x14(%esp)
f0104286:	8b 10                	mov    (%eax),%edx
f0104288:	89 54 24 10          	mov    %edx,0x10(%esp)
f010428c:	8b 50 10             	mov    0x10(%eax),%edx
f010428f:	89 54 24 0c          	mov    %edx,0xc(%esp)
f0104293:	8b 50 18             	mov    0x18(%eax),%edx
f0104296:	89 54 24 08          	mov    %edx,0x8(%esp)
f010429a:	8b 50 14             	mov    0x14(%eax),%edx
f010429d:	89 54 24 04          	mov    %edx,0x4(%esp)
f01042a1:	8b 40 1c             	mov    0x1c(%eax),%eax
f01042a4:	89 04 24             	mov    %eax,(%esp)
f01042a7:	e8 a4 04 00 00       	call   f0104750 <syscall>
f01042ac:	89 46 1c             	mov    %eax,0x1c(%esi)
  }
  return;
}
f01042af:	8b 75 f8             	mov    -0x8(%ebp),%esi
f01042b2:	8b 7d fc             	mov    -0x4(%ebp),%edi
f01042b5:	89 ec                	mov    %ebp,%esp
f01042b7:	5d                   	pop    %ebp
f01042b8:	c3                   	ret    

f01042b9 <page_fault_handler>:
  sched_yield();
}

void
page_fault_handler(struct Trapframe *tf)
{
f01042b9:	55                   	push   %ebp
f01042ba:	89 e5                	mov    %esp,%ebp
f01042bc:	83 ec 38             	sub    $0x38,%esp
f01042bf:	89 5d f4             	mov    %ebx,-0xc(%ebp)
f01042c2:	89 75 f8             	mov    %esi,-0x8(%ebp)
f01042c5:	89 7d fc             	mov    %edi,-0x4(%ebp)
f01042c8:	8b 5d 08             	mov    0x8(%ebp),%ebx

static __inline uint32_t
rcr2(void)
{
	uint32_t val;
	__asm __volatile("movl %%cr2,%0" : "=r" (val));
f01042cb:	0f 20 d6             	mov    %cr2,%esi
	// Read processor's CR2 register to find the faulting address
	fault_va = rcr2();

	// Handle kernel-mode page faults.
	// LAB 3: Your code here.
  if (tf->tf_cs == GD_KT) {
f01042ce:	66 83 7b 34 08       	cmpw   $0x8,0x34(%ebx)
f01042d3:	75 24                	jne    f01042f9 <page_fault_handler+0x40>
    print_trapframe(tf);
f01042d5:	89 1c 24             	mov    %ebx,(%esp)
f01042d8:	e8 3d fe ff ff       	call   f010411a <print_trapframe>
    panic("Kernel page fault\n");
f01042dd:	c7 44 24 08 94 7a 10 	movl   $0xf0107a94,0x8(%esp)
f01042e4:	f0 
f01042e5:	c7 44 24 04 30 01 00 	movl   $0x130,0x4(%esp)
f01042ec:	00 
f01042ed:	c7 04 24 88 7a 10 f0 	movl   $0xf0107a88,(%esp)
f01042f4:	e8 8c bd ff ff       	call   f0100085 <_panic>
	//   user_mem_assert() and env_run() are useful here.
	//   To change what the user environment runs, modify 'curenv->env_tf'
	//   (the 'tf' variable points at 'curenv->env_tf').

	// LAB 4: Your code here.
  if (curenv->env_pgfault_upcall != NULL) {
f01042f9:	a1 60 f2 2c f0       	mov    0xf02cf260,%eax
f01042fe:	83 78 64 00          	cmpl   $0x0,0x64(%eax)
f0104302:	0f 84 c3 00 00 00    	je     f01043cb <page_fault_handler+0x112>
 *    USTACKTOP  --->  +------------------------------+ 0xeebfe000
 *                     |      Normal User Stack       | RW/RW  PGSIZE
 *                     +------------------------------+ 0xeebfd000
 */

    if ((tf->tf_esp >= (UXSTACKTOP-PGSIZE))
f0104308:	8b 53 3c             	mov    0x3c(%ebx),%edx
f010430b:	8d 8a 00 10 40 11    	lea    0x11401000(%edx),%ecx
f0104311:	83 ea 38             	sub    $0x38,%edx
f0104314:	81 f9 00 10 00 00    	cmp    $0x1000,%ecx
f010431a:	b9 c8 ff bf ee       	mov    $0xeebfffc8,%ecx
f010431f:	0f 42 ca             	cmovb  %edx,%ecx
f0104322:	89 4d e4             	mov    %ecx,-0x1c(%ebp)
      // We are handling the case of recursive page fault.
      stackAddress    = tf->tf_esp-stackSize;
    } else {
      stackAddress    = UXSTACKTOP-stackSize;
    }
    utf = (struct UTrapframe *)stackAddress;
f0104325:	89 4d e0             	mov    %ecx,-0x20(%ebp)
    user_mem_assert(curenv, (void *)stackAddress, stackSize-1, PTE_P|PTE_U|PTE_W);
f0104328:	c7 44 24 0c 07 00 00 	movl   $0x7,0xc(%esp)
f010432f:	00 
f0104330:	c7 44 24 08 37 00 00 	movl   $0x37,0x8(%esp)
f0104337:	00 
f0104338:	89 4c 24 04          	mov    %ecx,0x4(%esp)
f010433c:	89 04 24             	mov    %eax,(%esp)
f010433f:	e8 a3 d0 ff ff       	call   f01013e7 <user_mem_assert>

    utf->utf_fault_va       = fault_va;
f0104344:	8b 45 e4             	mov    -0x1c(%ebp),%eax
f0104347:	89 30                	mov    %esi,(%eax)
    utf->utf_err            = tf->tf_err;
f0104349:	8b 43 2c             	mov    0x2c(%ebx),%eax
f010434c:	8b 55 e4             	mov    -0x1c(%ebp),%edx
f010434f:	89 42 04             	mov    %eax,0x4(%edx)
    utf->utf_regs           = tf->tf_regs;
f0104352:	89 d7                	mov    %edx,%edi
f0104354:	83 c7 08             	add    $0x8,%edi
f0104357:	89 de                	mov    %ebx,%esi
f0104359:	b8 20 00 00 00       	mov    $0x20,%eax
f010435e:	f7 c7 01 00 00 00    	test   $0x1,%edi
f0104364:	74 04                	je     f010436a <page_fault_handler+0xb1>
f0104366:	a4                   	movsb  %ds:(%esi),%es:(%edi)
f0104367:	83 e8 01             	sub    $0x1,%eax
f010436a:	f7 c7 02 00 00 00    	test   $0x2,%edi
f0104370:	74 05                	je     f0104377 <page_fault_handler+0xbe>
f0104372:	66 a5                	movsw  %ds:(%esi),%es:(%edi)
f0104374:	83 e8 02             	sub    $0x2,%eax
f0104377:	89 c1                	mov    %eax,%ecx
f0104379:	c1 e9 02             	shr    $0x2,%ecx
f010437c:	f3 a5                	rep movsl %ds:(%esi),%es:(%edi)
f010437e:	ba 00 00 00 00       	mov    $0x0,%edx
f0104383:	a8 02                	test   $0x2,%al
f0104385:	74 0b                	je     f0104392 <page_fault_handler+0xd9>
f0104387:	0f b7 0c 16          	movzwl (%esi,%edx,1),%ecx
f010438b:	66 89 0c 17          	mov    %cx,(%edi,%edx,1)
f010438f:	83 c2 02             	add    $0x2,%edx
f0104392:	a8 01                	test   $0x1,%al
f0104394:	74 07                	je     f010439d <page_fault_handler+0xe4>
f0104396:	0f b6 04 16          	movzbl (%esi,%edx,1),%eax
f010439a:	88 04 17             	mov    %al,(%edi,%edx,1)
    utf->utf_eip            = tf->tf_eip;
f010439d:	8b 43 30             	mov    0x30(%ebx),%eax
f01043a0:	8b 55 e0             	mov    -0x20(%ebp),%edx
f01043a3:	89 42 28             	mov    %eax,0x28(%edx)
    utf->utf_eflags         = tf->tf_eflags;
f01043a6:	8b 43 38             	mov    0x38(%ebx),%eax
f01043a9:	89 42 2c             	mov    %eax,0x2c(%edx)
    utf->utf_esp            = tf->tf_esp;
f01043ac:	8b 43 3c             	mov    0x3c(%ebx),%eax
f01043af:	89 42 30             	mov    %eax,0x30(%edx)
    tf->tf_eip              = (uint32_t)curenv->env_pgfault_upcall;
f01043b2:	a1 60 f2 2c f0       	mov    0xf02cf260,%eax
f01043b7:	8b 40 64             	mov    0x64(%eax),%eax
f01043ba:	89 43 30             	mov    %eax,0x30(%ebx)
    tf->tf_esp              = stackAddress;
f01043bd:	8b 45 e4             	mov    -0x1c(%ebp),%eax
f01043c0:	89 43 3c             	mov    %eax,0x3c(%ebx)
    env_pop_tf(tf);
f01043c3:	89 1c 24             	mov    %ebx,(%esp)
f01043c6:	e8 28 ed ff ff       	call   f01030f3 <env_pop_tf>
  }

	// Destroy the environment that caused the fault.
	cprintf("[%08x] user fault va %08x ip %08x\n",
f01043cb:	8b 53 30             	mov    0x30(%ebx),%edx
f01043ce:	89 54 24 0c          	mov    %edx,0xc(%esp)
f01043d2:	89 74 24 08          	mov    %esi,0x8(%esp)
f01043d6:	8b 40 4c             	mov    0x4c(%eax),%eax
f01043d9:	89 44 24 04          	mov    %eax,0x4(%esp)
f01043dd:	c7 04 24 40 7c 10 f0 	movl   $0xf0107c40,(%esp)
f01043e4:	e8 f6 f5 ff ff       	call   f01039df <cprintf>
		curenv->env_id, fault_va, tf->tf_eip);
	print_trapframe(tf);
f01043e9:	89 1c 24             	mov    %ebx,(%esp)
f01043ec:	e8 29 fd ff ff       	call   f010411a <print_trapframe>
	env_destroy(curenv);
f01043f1:	a1 60 f2 2c f0       	mov    0xf02cf260,%eax
f01043f6:	89 04 24             	mov    %eax,(%esp)
f01043f9:	e8 30 ef ff ff       	call   f010332e <env_destroy>
}
f01043fe:	8b 5d f4             	mov    -0xc(%ebp),%ebx
f0104401:	8b 75 f8             	mov    -0x8(%ebp),%esi
f0104404:	8b 7d fc             	mov    -0x4(%ebp),%edi
f0104407:	89 ec                	mov    %ebp,%esp
f0104409:	5d                   	pop    %ebp
f010440a:	c3                   	ret    

f010440b <timer_handler>:
	else
		sched_yield();
}

void
timer_handler(struct Trapframe *tf) {
f010440b:	55                   	push   %ebp
f010440c:	89 e5                	mov    %esp,%ebp
f010440e:	83 ec 08             	sub    $0x8,%esp
  // Handle timer interrupt for user mode process.
  time_tick();
f0104411:	e8 5c 22 00 00       	call   f0106672 <time_tick>
  sched_yield();
f0104416:	e8 75 02 00 00       	call   f0104690 <sched_yield>

f010441b <trap>:
	}
}

void
trap(struct Trapframe *tf)
{
f010441b:	55                   	push   %ebp
f010441c:	89 e5                	mov    %esp,%ebp
f010441e:	57                   	push   %edi
f010441f:	56                   	push   %esi
f0104420:	83 ec 10             	sub    $0x10,%esp
f0104423:	8b 75 08             	mov    0x8(%ebp),%esi
	// The environment may have set DF and some versions
	// of GCC rely on DF being clear
	asm volatile("cld" ::: "cc");
f0104426:	fc                   	cld    

static __inline uint32_t
read_eflags(void)
{
        uint32_t eflags;
        __asm __volatile("pushfl; popl %0" : "=r" (eflags));
f0104427:	9c                   	pushf  
f0104428:	58                   	pop    %eax
	// Check that interrupts are disabled.  If this assertion
	// fails, DO NOT be tempted to fix it by inserting a "cli" in
	// the interrupt path.
	assert(!(read_eflags() & FL_IF));
f0104429:	f6 c4 02             	test   $0x2,%ah
f010442c:	74 24                	je     f0104452 <trap+0x37>
f010442e:	c7 44 24 0c a7 7a 10 	movl   $0xf0107aa7,0xc(%esp)
f0104435:	f0 
f0104436:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f010443d:	f0 
f010443e:	c7 44 24 04 04 01 00 	movl   $0x104,0x4(%esp)
f0104445:	00 
f0104446:	c7 04 24 88 7a 10 f0 	movl   $0xf0107a88,(%esp)
f010444d:	e8 33 bc ff ff       	call   f0100085 <_panic>

	if ((tf->tf_cs & 3) == 3) {
f0104452:	0f b7 46 34          	movzwl 0x34(%esi),%eax
f0104456:	83 e0 03             	and    $0x3,%eax
f0104459:	83 f8 03             	cmp    $0x3,%eax
f010445c:	75 3c                	jne    f010449a <trap+0x7f>
		// Trapped from user mode.
		// Copy trap frame (which is currently on the stack)
		// into 'curenv->env_tf', so that running the environment
		// will restart at the trap point.
		assert(curenv);
f010445e:	a1 60 f2 2c f0       	mov    0xf02cf260,%eax
f0104463:	85 c0                	test   %eax,%eax
f0104465:	75 24                	jne    f010448b <trap+0x70>
f0104467:	c7 44 24 0c c0 7a 10 	movl   $0xf0107ac0,0xc(%esp)
f010446e:	f0 
f010446f:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0104476:	f0 
f0104477:	c7 44 24 04 0b 01 00 	movl   $0x10b,0x4(%esp)
f010447e:	00 
f010447f:	c7 04 24 88 7a 10 f0 	movl   $0xf0107a88,(%esp)
f0104486:	e8 fa bb ff ff       	call   f0100085 <_panic>
		curenv->env_tf = *tf;
f010448b:	b9 11 00 00 00       	mov    $0x11,%ecx
f0104490:	89 c7                	mov    %eax,%edi
f0104492:	f3 a5                	rep movsl %ds:(%esi),%es:(%edi)
		// The trapframe on the stack should be ignored from here on.
		tf = &curenv->env_tf;
f0104494:	8b 35 60 f2 2c f0    	mov    0xf02cf260,%esi
}

static void
trap_dispatch(struct Trapframe *tf)
{
  switch(tf->tf_trapno) {
f010449a:	8b 46 28             	mov    0x28(%esi),%eax
f010449d:	83 f8 30             	cmp    $0x30,%eax
f01044a0:	77 68                	ja     f010450a <trap+0xef>
f01044a2:	ff 24 85 80 7c 10 f0 	jmp    *-0xfef8380(,%eax,4)
    case T_PGFLT:
      page_fault_handler(tf);
f01044a9:	89 34 24             	mov    %esi,(%esp)
f01044ac:	e8 08 fe ff ff       	call   f01042b9 <page_fault_handler>
f01044b1:	e9 aa 00 00 00       	jmp    f0104560 <trap+0x145>
      return;
    case T_BRKPT:
      break_point_handler(tf);
f01044b6:	89 34 24             	mov    %esi,(%esp)
f01044b9:	e8 a2 fb ff ff       	call   f0104060 <break_point_handler>
f01044be:	66 90                	xchg   %ax,%ax
f01044c0:	e9 9b 00 00 00       	jmp    f0104560 <trap+0x145>
      return;
    case T_SYSCALL:
      syscall_handler(tf);
f01044c5:	89 34 24             	mov    %esi,(%esp)
f01044c8:	e8 53 fd ff ff       	call   f0104220 <syscall_handler>
f01044cd:	8d 76 00             	lea    0x0(%esi),%esi
f01044d0:	e9 8b 00 00 00       	jmp    f0104560 <trap+0x145>
      return;
    case T_DEBUG:
      debug_handler(tf);
f01044d5:	89 34 24             	mov    %esi,(%esp)
f01044d8:	e8 70 fb ff ff       	call   f010404d <debug_handler>
f01044dd:	8d 76 00             	lea    0x0(%esi),%esi
f01044e0:	eb 7e                	jmp    f0104560 <trap+0x145>
      return;
    case IRQ_OFFSET+IRQ_TIMER:
      timer_handler(tf);
f01044e2:	89 34 24             	mov    %esi,(%esp)
f01044e5:	e8 21 ff ff ff       	call   f010440b <timer_handler>
f01044ea:	8d b6 00 00 00 00    	lea    0x0(%esi),%esi
f01044f0:	eb 6e                	jmp    f0104560 <trap+0x145>
      return;
    case IRQ_OFFSET+IRQ_KBD:
      kbd_intr();
f01044f2:	e8 18 bd ff ff       	call   f010020f <kbd_intr>
f01044f7:	90                   	nop
f01044f8:	eb 66                	jmp    f0104560 <trap+0x145>
      return;
    case IRQ_OFFSET+IRQ_SERIAL:
      serial_intr();
f01044fa:	8d b6 00 00 00 00    	lea    0x0(%esi),%esi
f0104500:	e8 1c bd ff ff       	call   f0100221 <serial_intr>
f0104505:	8d 76 00             	lea    0x0(%esi),%esi
f0104508:	eb 56                	jmp    f0104560 <trap+0x145>
	// LAB 6: Your code here.

	// Handle spurious interrupts
	// The hardware sometimes raises these because of noise on the
	// IRQ line or other reasons. We don't care.
	if (tf->tf_trapno == IRQ_OFFSET + IRQ_SPURIOUS) {
f010450a:	83 f8 27             	cmp    $0x27,%eax
f010450d:	8d 76 00             	lea    0x0(%esi),%esi
f0104510:	75 16                	jne    f0104528 <trap+0x10d>
		cprintf("Spurious interrupt on irq 7\n");
f0104512:	c7 04 24 c7 7a 10 f0 	movl   $0xf0107ac7,(%esp)
f0104519:	e8 c1 f4 ff ff       	call   f01039df <cprintf>
		print_trapframe(tf);
f010451e:	89 34 24             	mov    %esi,(%esp)
f0104521:	e8 f4 fb ff ff       	call   f010411a <print_trapframe>
f0104526:	eb 38                	jmp    f0104560 <trap+0x145>

	// Handle keyboard and serial interrupts.
	// LAB 7: Your code here.

	// Unexpected trap: The user process or the kernel has a bug.
	print_trapframe(tf);
f0104528:	89 34 24             	mov    %esi,(%esp)
f010452b:	e8 ea fb ff ff       	call   f010411a <print_trapframe>
	if (tf->tf_cs == GD_KT)
f0104530:	66 83 7e 34 08       	cmpw   $0x8,0x34(%esi)
f0104535:	75 1c                	jne    f0104553 <trap+0x138>
		panic("unhandled trap in kernel");
f0104537:	c7 44 24 08 e4 7a 10 	movl   $0xf0107ae4,0x8(%esp)
f010453e:	f0 
f010453f:	c7 44 24 04 f4 00 00 	movl   $0xf4,0x4(%esp)
f0104546:	00 
f0104547:	c7 04 24 88 7a 10 f0 	movl   $0xf0107a88,(%esp)
f010454e:	e8 32 bb ff ff       	call   f0100085 <_panic>
	else {
		env_destroy(curenv);
f0104553:	a1 60 f2 2c f0       	mov    0xf02cf260,%eax
f0104558:	89 04 24             	mov    %eax,(%esp)
f010455b:	e8 ce ed ff ff       	call   f010332e <env_destroy>
	trap_dispatch(tf);

	// If we made it to this point, then no other environment was
	// scheduled, so we should return to the current environment
	// if doing so makes sense.
	if (curenv && curenv->env_status == ENV_RUNNABLE)
f0104560:	a1 60 f2 2c f0       	mov    0xf02cf260,%eax
f0104565:	85 c0                	test   %eax,%eax
f0104567:	74 0e                	je     f0104577 <trap+0x15c>
f0104569:	83 78 54 01          	cmpl   $0x1,0x54(%eax)
f010456d:	75 08                	jne    f0104577 <trap+0x15c>
		env_run(curenv);
f010456f:	89 04 24             	mov    %eax,(%esp)
f0104572:	e8 a8 eb ff ff       	call   f010311f <env_run>
	else
		sched_yield();
f0104577:	e8 14 01 00 00       	call   f0104690 <sched_yield>

f010457c <divideHandler>:

.text
/**
 * Lab 3: Your code here for generating entry points for the different traps.
 **/
    TRAPHANDLER_NOEC(divideHandler, T_DIVIDE)
f010457c:	6a 00                	push   $0x0
f010457e:	6a 00                	push   $0x0
f0104580:	e9 ef 00 00 00       	jmp    f0104674 <_alltraps>
f0104585:	90                   	nop

f0104586 <debugHandler>:
    TRAPHANDLER_NOEC(debugHandler, T_DEBUG)
f0104586:	6a 00                	push   $0x0
f0104588:	6a 01                	push   $0x1
f010458a:	e9 e5 00 00 00       	jmp    f0104674 <_alltraps>
f010458f:	90                   	nop

f0104590 <nmiHandler>:
    TRAPHANDLER_NOEC(nmiHandler, T_NMI)
f0104590:	6a 00                	push   $0x0
f0104592:	6a 02                	push   $0x2
f0104594:	e9 db 00 00 00       	jmp    f0104674 <_alltraps>
f0104599:	90                   	nop

f010459a <brkptHandler>:
    TRAPHANDLER_NOEC(brkptHandler, T_BRKPT)
f010459a:	6a 00                	push   $0x0
f010459c:	6a 03                	push   $0x3
f010459e:	e9 d1 00 00 00       	jmp    f0104674 <_alltraps>
f01045a3:	90                   	nop

f01045a4 <oflowHandler>:
    TRAPHANDLER_NOEC(oflowHandler, T_OFLOW)
f01045a4:	6a 00                	push   $0x0
f01045a6:	6a 04                	push   $0x4
f01045a8:	e9 c7 00 00 00       	jmp    f0104674 <_alltraps>
f01045ad:	90                   	nop

f01045ae <boundHandler>:
    TRAPHANDLER_NOEC(boundHandler, T_BOUND)
f01045ae:	6a 00                	push   $0x0
f01045b0:	6a 05                	push   $0x5
f01045b2:	e9 bd 00 00 00       	jmp    f0104674 <_alltraps>
f01045b7:	90                   	nop

f01045b8 <illopHandler>:
    TRAPHANDLER_NOEC(illopHandler, T_ILLOP)
f01045b8:	6a 00                	push   $0x0
f01045ba:	6a 06                	push   $0x6
f01045bc:	e9 b3 00 00 00       	jmp    f0104674 <_alltraps>
f01045c1:	90                   	nop

f01045c2 <deviceHandler>:
    TRAPHANDLER_NOEC(deviceHandler, T_DEVICE)
f01045c2:	6a 00                	push   $0x0
f01045c4:	6a 07                	push   $0x7
f01045c6:	e9 a9 00 00 00       	jmp    f0104674 <_alltraps>
f01045cb:	90                   	nop

f01045cc <dblFaultHandler>:
    TRAPHANDLER(dblFaultHandler, T_DBLFLT)
f01045cc:	6a 08                	push   $0x8
f01045ce:	e9 a1 00 00 00       	jmp    f0104674 <_alltraps>
f01045d3:	90                   	nop

f01045d4 <tssHandler>:

    TRAPHANDLER(tssHandler, T_TSS)
f01045d4:	6a 0a                	push   $0xa
f01045d6:	e9 99 00 00 00       	jmp    f0104674 <_alltraps>
f01045db:	90                   	nop

f01045dc <segnpHandler>:
    TRAPHANDLER(segnpHandler, T_SEGNP)
f01045dc:	6a 0b                	push   $0xb
f01045de:	e9 91 00 00 00       	jmp    f0104674 <_alltraps>
f01045e3:	90                   	nop

f01045e4 <stackHandler>:
    TRAPHANDLER(stackHandler, T_STACK)
f01045e4:	6a 0c                	push   $0xc
f01045e6:	e9 89 00 00 00       	jmp    f0104674 <_alltraps>
f01045eb:	90                   	nop

f01045ec <gpfltHandler>:
    TRAPHANDLER(gpfltHandler, T_GPFLT)
f01045ec:	6a 0d                	push   $0xd
f01045ee:	e9 81 00 00 00       	jmp    f0104674 <_alltraps>
f01045f3:	90                   	nop

f01045f4 <pgfltHandler>:
    TRAPHANDLER(pgfltHandler, T_PGFLT)
f01045f4:	6a 0e                	push   $0xe
f01045f6:	eb 7c                	jmp    f0104674 <_alltraps>

f01045f8 <fperrHandler>:

    TRAPHANDLER_NOEC(fperrHandler, T_FPERR)
f01045f8:	6a 00                	push   $0x0
f01045fa:	6a 10                	push   $0x10
f01045fc:	eb 76                	jmp    f0104674 <_alltraps>

f01045fe <alignHandler>:
    TRAPHANDLER(alignHandler, T_ALIGN)
f01045fe:	6a 11                	push   $0x11
f0104600:	eb 72                	jmp    f0104674 <_alltraps>

f0104602 <mchkHandler>:
    TRAPHANDLER_NOEC(mchkHandler, T_MCHK)
f0104602:	6a 00                	push   $0x0
f0104604:	6a 12                	push   $0x12
f0104606:	eb 6c                	jmp    f0104674 <_alltraps>

f0104608 <simderrHandler>:
    TRAPHANDLER_NOEC(simderrHandler, T_SIMDERR)
f0104608:	6a 00                	push   $0x0
f010460a:	6a 13                	push   $0x13
f010460c:	eb 66                	jmp    f0104674 <_alltraps>

f010460e <irq32Handler>:

/**
 * Device IRQs
 **/
    TRAPHANDLER_NOEC(irq32Handler, 32)
f010460e:	6a 00                	push   $0x0
f0104610:	6a 20                	push   $0x20
f0104612:	eb 60                	jmp    f0104674 <_alltraps>

f0104614 <irq33Handler>:
    TRAPHANDLER_NOEC(irq33Handler, 33)
f0104614:	6a 00                	push   $0x0
f0104616:	6a 21                	push   $0x21
f0104618:	eb 5a                	jmp    f0104674 <_alltraps>

f010461a <irq34Handler>:
    TRAPHANDLER_NOEC(irq34Handler, 34)
f010461a:	6a 00                	push   $0x0
f010461c:	6a 22                	push   $0x22
f010461e:	eb 54                	jmp    f0104674 <_alltraps>

f0104620 <irq35Handler>:
    TRAPHANDLER_NOEC(irq35Handler, 35)
f0104620:	6a 00                	push   $0x0
f0104622:	6a 23                	push   $0x23
f0104624:	eb 4e                	jmp    f0104674 <_alltraps>

f0104626 <irq36Handler>:
    TRAPHANDLER_NOEC(irq36Handler, 36)
f0104626:	6a 00                	push   $0x0
f0104628:	6a 24                	push   $0x24
f010462a:	eb 48                	jmp    f0104674 <_alltraps>

f010462c <irq37Handler>:
    TRAPHANDLER_NOEC(irq37Handler, 37)
f010462c:	6a 00                	push   $0x0
f010462e:	6a 25                	push   $0x25
f0104630:	eb 42                	jmp    f0104674 <_alltraps>

f0104632 <irq38Handler>:
    TRAPHANDLER_NOEC(irq38Handler, 38)
f0104632:	6a 00                	push   $0x0
f0104634:	6a 26                	push   $0x26
f0104636:	eb 3c                	jmp    f0104674 <_alltraps>

f0104638 <irq39Handler>:
    TRAPHANDLER_NOEC(irq39Handler, 39)
f0104638:	6a 00                	push   $0x0
f010463a:	6a 27                	push   $0x27
f010463c:	eb 36                	jmp    f0104674 <_alltraps>

f010463e <irq40Handler>:
    TRAPHANDLER_NOEC(irq40Handler, 40)
f010463e:	6a 00                	push   $0x0
f0104640:	6a 28                	push   $0x28
f0104642:	eb 30                	jmp    f0104674 <_alltraps>

f0104644 <irq41Handler>:
    TRAPHANDLER_NOEC(irq41Handler, 41)
f0104644:	6a 00                	push   $0x0
f0104646:	6a 29                	push   $0x29
f0104648:	eb 2a                	jmp    f0104674 <_alltraps>

f010464a <irq42Handler>:
    TRAPHANDLER_NOEC(irq42Handler, 42)
f010464a:	6a 00                	push   $0x0
f010464c:	6a 2a                	push   $0x2a
f010464e:	eb 24                	jmp    f0104674 <_alltraps>

f0104650 <irq43Handler>:
    TRAPHANDLER_NOEC(irq43Handler, 43)
f0104650:	6a 00                	push   $0x0
f0104652:	6a 2b                	push   $0x2b
f0104654:	eb 1e                	jmp    f0104674 <_alltraps>

f0104656 <irq44Handler>:
    TRAPHANDLER_NOEC(irq44Handler, 44)
f0104656:	6a 00                	push   $0x0
f0104658:	6a 2c                	push   $0x2c
f010465a:	eb 18                	jmp    f0104674 <_alltraps>

f010465c <irq45Handler>:
    TRAPHANDLER_NOEC(irq45Handler, 45)
f010465c:	6a 00                	push   $0x0
f010465e:	6a 2d                	push   $0x2d
f0104660:	eb 12                	jmp    f0104674 <_alltraps>

f0104662 <irq46Handler>:
    TRAPHANDLER_NOEC(irq46Handler, 46)
f0104662:	6a 00                	push   $0x0
f0104664:	6a 2e                	push   $0x2e
f0104666:	eb 0c                	jmp    f0104674 <_alltraps>

f0104668 <irq47Handler>:
    TRAPHANDLER_NOEC(irq47Handler, 47)
f0104668:	6a 00                	push   $0x0
f010466a:	6a 2f                	push   $0x2f
f010466c:	eb 06                	jmp    f0104674 <_alltraps>

f010466e <syscallHandler>:
    TRAPHANDLER_NOEC(syscallHandler, T_SYSCALL)
f010466e:	6a 00                	push   $0x0
f0104670:	6a 30                	push   $0x30
f0104672:	eb 00                	jmp    f0104674 <_alltraps>

f0104674 <_alltraps>:

/*
 * Lab 3: Your code here for _alltraps
 */
    _alltraps:
    pushl %ds
f0104674:	1e                   	push   %ds
    pushl %es
f0104675:	06                   	push   %es
    pushal
f0104676:	60                   	pusha  
    movl $GD_KD, %eax
f0104677:	b8 10 00 00 00       	mov    $0x10,%eax
    movw %ax, %ds
f010467c:	8e d8                	mov    %eax,%ds
    movw %ax, %es
f010467e:	8e c0                	mov    %eax,%es
    push %esp
f0104680:	54                   	push   %esp
    call trap
f0104681:	e8 95 fd ff ff       	call   f010441b <trap>
    pop %esp
f0104686:	5c                   	pop    %esp
    popal
f0104687:	61                   	popa   
    popl %es
f0104688:	07                   	pop    %es
    popl %ds
f0104689:	1f                   	pop    %ds
    sub $0x8, %esp
f010468a:	83 ec 08             	sub    $0x8,%esp
    iret
f010468d:	cf                   	iret   
	...

f0104690 <sched_yield>:


// Choose a user environment to run and run it.
void
sched_yield(void)
{
f0104690:	55                   	push   %ebp
f0104691:	89 e5                	mov    %esp,%ebp
f0104693:	57                   	push   %edi
f0104694:	56                   	push   %esi
f0104695:	53                   	push   %ebx
f0104696:	83 ec 1c             	sub    $0x1c,%esp
	// unless NOTHING else is runnable.

	// LAB 4: Your code here.
  // Get the curenv Id. We should start searching from the environment
  // after the current one.
  if (curenv != NULL) {
f0104699:	8b 1d 60 f2 2c f0    	mov    0xf02cf260,%ebx
f010469f:	85 db                	test   %ebx,%ebx
f01046a1:	75 12                	jne    f01046b5 <sched_yield+0x25>
f01046a3:	be 00 00 00 00       	mov    $0x0,%esi
f01046a8:	b8 01 00 00 00       	mov    $0x1,%eax
    startEnv    = (int)(&envs[ENVX(curenv->env_id)] - envs);
  }

  for (i=startEnv+1; i!=startEnv;i=((i+1)%(NENV-1))) {
    if (i != 0 && envs[i].env_status == ENV_RUNNABLE) {
f01046ad:	8b 3d 5c f2 2c f0    	mov    0xf02cf25c,%edi
f01046b3:	eb 1a                	jmp    f01046cf <sched_yield+0x3f>

	// LAB 4: Your code here.
  // Get the curenv Id. We should start searching from the environment
  // after the current one.
  if (curenv != NULL) {
    startEnv    = (int)(&envs[ENVX(curenv->env_id)] - envs);
f01046b5:	8b 73 4c             	mov    0x4c(%ebx),%esi
f01046b8:	81 e6 ff 03 00 00    	and    $0x3ff,%esi
f01046be:	6b f6 7c             	imul   $0x7c,%esi,%esi
f01046c1:	c1 fe 02             	sar    $0x2,%esi
f01046c4:	69 f6 df 7b ef bd    	imul   $0xbdef7bdf,%esi,%esi
  }

  for (i=startEnv+1; i!=startEnv;i=((i+1)%(NENV-1))) {
f01046ca:	8d 46 01             	lea    0x1(%esi),%eax
f01046cd:	eb de                	jmp    f01046ad <sched_yield+0x1d>
    if (i != 0 && envs[i].env_status == ENV_RUNNABLE) {
f01046cf:	85 c0                	test   %eax,%eax
f01046d1:	74 0a                	je     f01046dd <sched_yield+0x4d>
f01046d3:	6b d0 7c             	imul   $0x7c,%eax,%edx
f01046d6:	83 7c 3a 54 01       	cmpl   $0x1,0x54(%edx,%edi,1)
f01046db:	74 6b                	je     f0104748 <sched_yield+0xb8>
  // after the current one.
  if (curenv != NULL) {
    startEnv    = (int)(&envs[ENVX(curenv->env_id)] - envs);
  }

  for (i=startEnv+1; i!=startEnv;i=((i+1)%(NENV-1))) {
f01046dd:	8d 48 01             	lea    0x1(%eax),%ecx
f01046e0:	b8 03 08 20 80       	mov    $0x80200803,%eax
f01046e5:	f7 e9                	imul   %ecx
f01046e7:	8d 04 0a             	lea    (%edx,%ecx,1),%eax
f01046ea:	c1 f8 09             	sar    $0x9,%eax
f01046ed:	89 ca                	mov    %ecx,%edx
f01046ef:	c1 fa 1f             	sar    $0x1f,%edx
f01046f2:	29 d0                	sub    %edx,%eax
f01046f4:	89 c2                	mov    %eax,%edx
f01046f6:	c1 e2 0a             	shl    $0xa,%edx
f01046f9:	29 c2                	sub    %eax,%edx
f01046fb:	29 d1                	sub    %edx,%ecx
f01046fd:	89 c8                	mov    %ecx,%eax
f01046ff:	39 ce                	cmp    %ecx,%esi
f0104701:	75 cc                	jne    f01046cf <sched_yield+0x3f>
        break;
    }
  }

  // Check if we can run current environement
  if (startEnv==0 && curenv!=NULL && curenv->env_status==ENV_RUNNABLE) {
f0104703:	85 f6                	test   %esi,%esi
f0104705:	75 14                	jne    f010471b <sched_yield+0x8b>
f0104707:	85 db                	test   %ebx,%ebx
f0104709:	74 10                	je     f010471b <sched_yield+0x8b>
f010470b:	83 7b 54 01          	cmpl   $0x1,0x54(%ebx)
f010470f:	90                   	nop
f0104710:	75 09                	jne    f010471b <sched_yield+0x8b>
    startEnv    = ENVX(curenv->env_id);
f0104712:	8b 73 4c             	mov    0x4c(%ebx),%esi
f0104715:	81 e6 ff 03 00 00    	and    $0x3ff,%esi
  }

	// Run the special idle environment when nothing else is runnable.
	if (envs[startEnv].env_status == ENV_RUNNABLE) {
f010471b:	6b f6 7c             	imul   $0x7c,%esi,%esi
f010471e:	01 f7                	add    %esi,%edi
f0104720:	83 7f 54 01          	cmpl   $0x1,0x54(%edi)
f0104724:	75 08                	jne    f010472e <sched_yield+0x9e>
		env_run(&envs[startEnv]);
f0104726:	89 3c 24             	mov    %edi,(%esp)
f0104729:	e8 f1 e9 ff ff       	call   f010311f <env_run>
  }
	else {
		cprintf("Destroyed all environments - nothing more to do!\n");
f010472e:	c7 04 24 b0 7d 10 f0 	movl   $0xf0107db0,(%esp)
f0104735:	e8 a5 f2 ff ff       	call   f01039df <cprintf>
		while (1)
			monitor(NULL);
f010473a:	c7 04 24 00 00 00 00 	movl   $0x0,(%esp)
f0104741:	e8 aa c2 ff ff       	call   f01009f0 <monitor>
f0104746:	eb f2                	jmp    f010473a <sched_yield+0xaa>
  if (startEnv==0 && curenv!=NULL && curenv->env_status==ENV_RUNNABLE) {
    startEnv    = ENVX(curenv->env_id);
  }

	// Run the special idle environment when nothing else is runnable.
	if (envs[startEnv].env_status == ENV_RUNNABLE) {
f0104748:	6b c0 7c             	imul   $0x7c,%eax,%eax
f010474b:	01 c7                	add    %eax,%edi
f010474d:	eb d7                	jmp    f0104726 <sched_yield+0x96>
	...

f0104750 <syscall>:
}

// Dispatches to the correct kernel function, passing the arguments.
int32_t
syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4, uint32_t a5)
{
f0104750:	55                   	push   %ebp
f0104751:	89 e5                	mov    %esp,%ebp
f0104753:	83 ec 38             	sub    $0x38,%esp
f0104756:	89 5d f4             	mov    %ebx,-0xc(%ebp)
f0104759:	89 75 f8             	mov    %esi,-0x8(%ebp)
f010475c:	89 7d fc             	mov    %edi,-0x4(%ebp)
f010475f:	8b 45 08             	mov    0x8(%ebp),%eax
f0104762:	8b 75 0c             	mov    0xc(%ebp),%esi
f0104765:	8b 7d 10             	mov    0x10(%ebp),%edi
	// Call the function corresponding to the 'syscallno' parameter.
	// Return any appropriate return value.
	// LAB 3: Your code here.
  switch(syscallno) {
f0104768:	83 f8 10             	cmp    $0x10,%eax
f010476b:	0f 87 28 06 00 00    	ja     f0104d99 <syscall+0x649>
f0104771:	ff 24 85 10 7e 10 f0 	jmp    *-0xfef81f0(,%eax,4)
static void
sys_cputs(const char *s, size_t len)
{
	// Check that the user has permission to read memory [s, s+len).
	// Destroy the environment if not.
    user_mem_assert(curenv, s, len, PTE_P); 
f0104778:	c7 44 24 0c 01 00 00 	movl   $0x1,0xc(%esp)
f010477f:	00 
f0104780:	89 7c 24 08          	mov    %edi,0x8(%esp)
f0104784:	89 74 24 04          	mov    %esi,0x4(%esp)
f0104788:	a1 60 f2 2c f0       	mov    0xf02cf260,%eax
f010478d:	89 04 24             	mov    %eax,(%esp)
f0104790:	e8 52 cc ff ff       	call   f01013e7 <user_mem_assert>
    cprintf("%.*s", len, s);
f0104795:	89 74 24 08          	mov    %esi,0x8(%esp)
f0104799:	89 7c 24 04          	mov    %edi,0x4(%esp)
f010479d:	c7 04 24 e2 7d 10 f0 	movl   $0xf0107de2,(%esp)
f01047a4:	e8 36 f2 ff ff       	call   f01039df <cprintf>
	// Return any appropriate return value.
	// LAB 3: Your code here.
  switch(syscallno) {
    case SYS_cputs:
      sys_cputs((char *)a1, a2);
      return a2;
f01047a9:	89 f8                	mov    %edi,%eax
f01047ab:	e9 05 06 00 00       	jmp    f0104db5 <syscall+0x665>
// Read a character from the system console without blocking.
// Returns the character, or 0 if there is no input waiting.
static int
sys_cgetc(void)
{
	return cons_getc();
f01047b0:	e8 87 ba ff ff       	call   f010023c <cons_getc>
  switch(syscallno) {
    case SYS_cputs:
      sys_cputs((char *)a1, a2);
      return a2;
    case SYS_cgetc:
      return sys_cgetc();
f01047b5:	e9 fb 05 00 00       	jmp    f0104db5 <syscall+0x665>

// Returns the current environment's envid.
static envid_t
sys_getenvid(void)
{
	return curenv->env_id;
f01047ba:	a1 60 f2 2c f0       	mov    0xf02cf260,%eax
f01047bf:	8b 40 4c             	mov    0x4c(%eax),%eax
      sys_cputs((char *)a1, a2);
      return a2;
    case SYS_cgetc:
      return sys_cgetc();
    case SYS_getenvid:
      return sys_getenvid();
f01047c2:	e9 ee 05 00 00       	jmp    f0104db5 <syscall+0x665>
sys_env_destroy(envid_t envid)
{
	int r;
	struct Env *e;

	if ((r = envid2env(envid, &e, 1)) < 0)
f01047c7:	c7 44 24 08 01 00 00 	movl   $0x1,0x8(%esp)
f01047ce:	00 
f01047cf:	8d 45 dc             	lea    -0x24(%ebp),%eax
f01047d2:	89 44 24 04          	mov    %eax,0x4(%esp)
f01047d6:	89 34 24             	mov    %esi,(%esp)
f01047d9:	e8 a2 e8 ff ff       	call   f0103080 <envid2env>
f01047de:	85 c0                	test   %eax,%eax
f01047e0:	0f 88 cf 05 00 00    	js     f0104db5 <syscall+0x665>
		return r;
	env_destroy(e);
f01047e6:	8b 45 dc             	mov    -0x24(%ebp),%eax
f01047e9:	89 04 24             	mov    %eax,(%esp)
f01047ec:	e8 3d eb ff ff       	call   f010332e <env_destroy>
f01047f1:	b8 00 00 00 00       	mov    $0x0,%eax
f01047f6:	e9 ba 05 00 00       	jmp    f0104db5 <syscall+0x665>

// Deschedule current environment and pick a different one to run.
static void
sys_yield(void)
{
	sched_yield();
f01047fb:	e8 90 fe ff ff       	call   f0104690 <sched_yield>
	// status is set to ENV_NOT_RUNNABLE, and the register set is copied
	// from the current environment -- but tweaked so sys_exofork
	// will appear to return 0.

	// LAB 4: Your code here.
    struct Env *newEnv  = NULL;
f0104800:	c7 45 dc 00 00 00 00 	movl   $0x0,-0x24(%ebp)
    int i,r;
    if (!(r=env_alloc(&newEnv, curenv->env_id))) {
f0104807:	a1 60 f2 2c f0       	mov    0xf02cf260,%eax
f010480c:	8b 40 4c             	mov    0x4c(%eax),%eax
f010480f:	89 44 24 04          	mov    %eax,0x4(%esp)
f0104813:	8d 45 dc             	lea    -0x24(%ebp),%eax
f0104816:	89 04 24             	mov    %eax,(%esp)
f0104819:	e8 b9 ec ff ff       	call   f01034d7 <env_alloc>
f010481e:	85 c0                	test   %eax,%eax
f0104820:	75 31                	jne    f0104853 <syscall+0x103>
      newEnv->env_tf                  = curenv->env_tf;
f0104822:	8b 45 dc             	mov    -0x24(%ebp),%eax
f0104825:	8b 35 60 f2 2c f0    	mov    0xf02cf260,%esi
f010482b:	b9 11 00 00 00       	mov    $0x11,%ecx
f0104830:	89 c7                	mov    %eax,%edi
f0104832:	f3 a5                	rep movsl %ds:(%esi),%es:(%edi)
      newEnv->env_tf.tf_regs.reg_eax  = 0;
f0104834:	8b 45 dc             	mov    -0x24(%ebp),%eax
f0104837:	c7 40 1c 00 00 00 00 	movl   $0x0,0x1c(%eax)
      newEnv->env_status              = ENV_NOT_RUNNABLE;
f010483e:	8b 45 dc             	mov    -0x24(%ebp),%eax
f0104841:	c7 40 54 02 00 00 00 	movl   $0x2,0x54(%eax)
    } else
      panic("Failed: %e", r);
    return newEnv->env_id;
f0104848:	8b 45 dc             	mov    -0x24(%ebp),%eax
f010484b:	8b 40 4c             	mov    0x4c(%eax),%eax
      return sys_env_destroy((envid_t)a1);
    case SYS_yield:
      sys_yield();
      return 0;
    case SYS_exofork:
      return sys_exofork();
f010484e:	e9 62 05 00 00       	jmp    f0104db5 <syscall+0x665>
    if (!(r=env_alloc(&newEnv, curenv->env_id))) {
      newEnv->env_tf                  = curenv->env_tf;
      newEnv->env_tf.tf_regs.reg_eax  = 0;
      newEnv->env_status              = ENV_NOT_RUNNABLE;
    } else
      panic("Failed: %e", r);
f0104853:	89 44 24 0c          	mov    %eax,0xc(%esp)
f0104857:	c7 44 24 08 be 78 10 	movl   $0xf01078be,0x8(%esp)
f010485e:	f0 
f010485f:	c7 44 24 04 59 00 00 	movl   $0x59,0x4(%esp)
f0104866:	00 
f0104867:	c7 04 24 e7 7d 10 f0 	movl   $0xf0107de7,(%esp)
f010486e:	e8 12 b8 ff ff       	call   f0100085 <_panic>
	// You should set envid2env's third argument to 1, which will
	// check whether the current environment has permission to set
	// envid's status.

	// LAB 4: Your code here.
    struct Env *env = NULL;
f0104873:	c7 45 dc 00 00 00 00 	movl   $0x0,-0x24(%ebp)
    
    if (status!=ENV_RUNNABLE && status!=ENV_NOT_RUNNABLE) {
f010487a:	8d 47 ff             	lea    -0x1(%edi),%eax
f010487d:	83 f8 01             	cmp    $0x1,%eax
f0104880:	76 0a                	jbe    f010488c <syscall+0x13c>
f0104882:	b8 fd ff ff ff       	mov    $0xfffffffd,%eax
f0104887:	e9 29 05 00 00       	jmp    f0104db5 <syscall+0x665>
        return -E_INVAL;
    }

    if (!envid2env(envid, &env, 1)) {
f010488c:	c7 44 24 08 01 00 00 	movl   $0x1,0x8(%esp)
f0104893:	00 
f0104894:	8d 45 dc             	lea    -0x24(%ebp),%eax
f0104897:	89 44 24 04          	mov    %eax,0x4(%esp)
f010489b:	89 34 24             	mov    %esi,(%esp)
f010489e:	e8 dd e7 ff ff       	call   f0103080 <envid2env>
f01048a3:	89 c2                	mov    %eax,%edx
f01048a5:	b8 fe ff ff ff       	mov    $0xfffffffe,%eax
f01048aa:	85 d2                	test   %edx,%edx
f01048ac:	0f 85 03 05 00 00    	jne    f0104db5 <syscall+0x665>
        env->env_status = status;
f01048b2:	8b 45 dc             	mov    -0x24(%ebp),%eax
f01048b5:	89 78 54             	mov    %edi,0x54(%eax)
f01048b8:	b8 00 00 00 00       	mov    $0x0,%eax
f01048bd:	e9 f3 04 00 00       	jmp    f0104db5 <syscall+0x665>
    case SYS_exofork:
      return sys_exofork();
    case SYS_env_set_status:
      return sys_env_set_status((envid_t)a1, (int)a2);
    case SYS_page_alloc:
      return sys_page_alloc((envid_t)a1, (void *)a2, a3);
f01048c2:	8b 5d 14             	mov    0x14(%ebp),%ebx
	//   page_insert() from kern/pmap.c.
	//   Most of the new code you write should be to check the
	//   parameters for correctness.
	//   If page_insert() fails, remember to free the page you
	//   allocated!
  struct Page *newPage    = NULL;
f01048c5:	c7 45 dc 00 00 00 00 	movl   $0x0,-0x24(%ebp)
  struct Env *env         = NULL;
f01048cc:	c7 45 e4 00 00 00 00 	movl   $0x0,-0x1c(%ebp)

  // Check if permissions are valid.
  if ((perm & (PTE_U|PTE_P)) != (PTE_U|PTE_P))
f01048d3:	89 d8                	mov    %ebx,%eax
f01048d5:	83 e0 05             	and    $0x5,%eax
f01048d8:	83 f8 05             	cmp    $0x5,%eax
f01048db:	0f 85 13 01 00 00    	jne    f01049f4 <syscall+0x2a4>
    return -E_INVAL;

  // Check if va is valid.
  if (((uint32_t)va >= UTOP)
f01048e1:	81 ff ff ff bf ee    	cmp    $0xeebfffff,%edi
f01048e7:	0f 87 07 01 00 00    	ja     f01049f4 <syscall+0x2a4>
f01048ed:	f7 c7 ff 0f 00 00    	test   $0xfff,%edi
f01048f3:	0f 85 fb 00 00 00    	jne    f01049f4 <syscall+0x2a4>
    || ((uint32_t)va & 0xFFF))
    return -E_INVAL;

  // Check if request is from a privileged environment.
  if (envid2env(envid, &env, 1))
f01048f9:	c7 44 24 08 01 00 00 	movl   $0x1,0x8(%esp)
f0104900:	00 
f0104901:	8d 45 e4             	lea    -0x1c(%ebp),%eax
f0104904:	89 44 24 04          	mov    %eax,0x4(%esp)
f0104908:	89 34 24             	mov    %esi,(%esp)
f010490b:	e8 70 e7 ff ff       	call   f0103080 <envid2env>
f0104910:	89 c2                	mov    %eax,%edx
f0104912:	b8 fe ff ff ff       	mov    $0xfffffffe,%eax
f0104917:	85 d2                	test   %edx,%edx
f0104919:	0f 85 96 04 00 00    	jne    f0104db5 <syscall+0x665>
    return -E_BAD_ENV;

  // Allocate Page Here.
  if (!(page_alloc(&newPage))) {
f010491f:	8d 45 dc             	lea    -0x24(%ebp),%eax
f0104922:	89 04 24             	mov    %eax,(%esp)
f0104925:	e8 a1 c7 ff ff       	call   f01010cb <page_alloc>
f010492a:	89 c2                	mov    %eax,%edx
f010492c:	b8 fc ff ff ff       	mov    $0xfffffffc,%eax
f0104931:	85 d2                	test   %edx,%edx
f0104933:	0f 85 7c 04 00 00    	jne    f0104db5 <syscall+0x665>
    memset(newPage, 0, sizeof(struct Page));
f0104939:	c7 44 24 08 0c 00 00 	movl   $0xc,0x8(%esp)
f0104940:	00 
f0104941:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
f0104948:	00 
f0104949:	8b 45 dc             	mov    -0x24(%ebp),%eax
f010494c:	89 04 24             	mov    %eax,(%esp)
f010494f:	e8 52 11 00 00       	call   f0105aa6 <memset>
}

static inline physaddr_t
page2pa(struct Page *pp)
{
	return page2ppn(pp) << PGSHIFT;
f0104954:	8b 45 dc             	mov    -0x24(%ebp),%eax
f0104957:	2b 05 2c ff 2c f0    	sub    0xf02cff2c,%eax
f010495d:	c1 f8 02             	sar    $0x2,%eax
f0104960:	69 c0 ab aa aa aa    	imul   $0xaaaaaaab,%eax,%eax
f0104966:	c1 e0 0c             	shl    $0xc,%eax
}

static inline void*
page2kva(struct Page *pp)
{
	return KADDR(page2pa(pp));
f0104969:	89 c2                	mov    %eax,%edx
f010496b:	c1 ea 0c             	shr    $0xc,%edx
f010496e:	3b 15 20 ff 2c f0    	cmp    0xf02cff20,%edx
f0104974:	72 20                	jb     f0104996 <syscall+0x246>
f0104976:	89 44 24 0c          	mov    %eax,0xc(%esp)
f010497a:	c7 44 24 08 50 70 10 	movl   $0xf0107050,0x8(%esp)
f0104981:	f0 
f0104982:	c7 44 24 04 5a 00 00 	movl   $0x5a,0x4(%esp)
f0104989:	00 
f010498a:	c7 04 24 7d 6c 10 f0 	movl   $0xf0106c7d,(%esp)
f0104991:	e8 ef b6 ff ff       	call   f0100085 <_panic>
    memset(page2kva(newPage), 0, PGSIZE);
f0104996:	c7 44 24 08 00 10 00 	movl   $0x1000,0x8(%esp)
f010499d:	00 
f010499e:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
f01049a5:	00 
f01049a6:	2d 00 00 00 10       	sub    $0x10000000,%eax
f01049ab:	89 04 24             	mov    %eax,(%esp)
f01049ae:	e8 f3 10 00 00       	call   f0105aa6 <memset>
    if (page_insert(env->env_pgdir, newPage, va, perm)) {
f01049b3:	89 5c 24 0c          	mov    %ebx,0xc(%esp)
f01049b7:	89 7c 24 08          	mov    %edi,0x8(%esp)
f01049bb:	8b 45 dc             	mov    -0x24(%ebp),%eax
f01049be:	89 44 24 04          	mov    %eax,0x4(%esp)
f01049c2:	8b 45 e4             	mov    -0x1c(%ebp),%eax
f01049c5:	8b 40 5c             	mov    0x5c(%eax),%eax
f01049c8:	89 04 24             	mov    %eax,(%esp)
f01049cb:	e8 c7 ca ff ff       	call   f0101497 <page_insert>
f01049d0:	89 c2                	mov    %eax,%edx
f01049d2:	b8 00 00 00 00       	mov    $0x0,%eax
f01049d7:	85 d2                	test   %edx,%edx
f01049d9:	0f 84 d6 03 00 00    	je     f0104db5 <syscall+0x665>
        page_free(newPage);
f01049df:	8b 45 dc             	mov    -0x24(%ebp),%eax
f01049e2:	89 04 24             	mov    %eax,(%esp)
f01049e5:	e8 95 c5 ff ff       	call   f0100f7f <page_free>
f01049ea:	b8 fc ff ff ff       	mov    $0xfffffffc,%eax
f01049ef:	e9 c1 03 00 00       	jmp    f0104db5 <syscall+0x665>
f01049f4:	b8 fd ff ff ff       	mov    $0xfffffffd,%eax
f01049f9:	e9 b7 03 00 00       	jmp    f0104db5 <syscall+0x665>
    case SYS_env_set_status:
      return sys_env_set_status((envid_t)a1, (int)a2);
    case SYS_page_alloc:
      return sys_page_alloc((envid_t)a1, (void *)a2, a3);
    case SYS_page_map:
      return sys_page_map((envid_t)a1, (void *)a2, (envid_t)a3, (void *)a4, (int)a5);
f01049fe:	8b 5d 1c             	mov    0x1c(%ebp),%ebx
	//   page_insert() from kern/pmap.c.
	//   Again, most of the new code you write should be to check the
	//   parameters for correctness.
	//   Use the third argument to page_lookup() to
	//   check the current permissions on the page.
    struct Env *srcEnv      = NULL;
f0104a01:	c7 45 e4 00 00 00 00 	movl   $0x0,-0x1c(%ebp)
    struct Env *dstEnv      = NULL;
f0104a08:	c7 45 dc 00 00 00 00 	movl   $0x0,-0x24(%ebp)
    pte_t *srcPte           = NULL;
f0104a0f:	c7 45 e0 00 00 00 00 	movl   $0x0,-0x20(%ebp)
    struct Page *page       = NULL;

    // Check if permissions are valid.
    if ((perm & (PTE_U|PTE_P)) != (PTE_U|PTE_P)) {
f0104a16:	89 d8                	mov    %ebx,%eax
f0104a18:	83 e0 05             	and    $0x5,%eax
f0104a1b:	83 f8 05             	cmp    $0x5,%eax
f0104a1e:	0f 85 a0 00 00 00    	jne    f0104ac4 <syscall+0x374>
        return -E_INVAL;
    }

    // Check if va is valid.
    if (((uint32_t)srcva >= UTOP)
f0104a24:	81 ff ff ff bf ee    	cmp    $0xeebfffff,%edi
f0104a2a:	0f 87 94 00 00 00    	ja     f0104ac4 <syscall+0x374>
f0104a30:	81 7d 18 ff ff bf ee 	cmpl   $0xeebfffff,0x18(%ebp)
f0104a37:	0f 87 87 00 00 00    	ja     f0104ac4 <syscall+0x374>
        || ((uint32_t)dstva >= UTOP))
        return -E_INVAL;

    // Check if request is from a privileged environment.
    if (envid2env(srcenvid, &srcEnv, 1) || envid2env(dstenvid, &dstEnv, 1)) {
f0104a3d:	c7 44 24 08 01 00 00 	movl   $0x1,0x8(%esp)
f0104a44:	00 
f0104a45:	8d 45 e4             	lea    -0x1c(%ebp),%eax
f0104a48:	89 44 24 04          	mov    %eax,0x4(%esp)
f0104a4c:	89 34 24             	mov    %esi,(%esp)
f0104a4f:	e8 2c e6 ff ff       	call   f0103080 <envid2env>
f0104a54:	85 c0                	test   %eax,%eax
f0104a56:	75 76                	jne    f0104ace <syscall+0x37e>
f0104a58:	c7 44 24 08 01 00 00 	movl   $0x1,0x8(%esp)
f0104a5f:	00 
f0104a60:	8d 45 dc             	lea    -0x24(%ebp),%eax
f0104a63:	89 44 24 04          	mov    %eax,0x4(%esp)
f0104a67:	8b 45 14             	mov    0x14(%ebp),%eax
f0104a6a:	89 04 24             	mov    %eax,(%esp)
f0104a6d:	e8 0e e6 ff ff       	call   f0103080 <envid2env>
f0104a72:	85 c0                	test   %eax,%eax
f0104a74:	75 58                	jne    f0104ace <syscall+0x37e>
        return -E_BAD_ENV;
    }

    if ((page=page_lookup(srcEnv->env_pgdir, srcva, &srcPte))) {
f0104a76:	8d 45 e0             	lea    -0x20(%ebp),%eax
f0104a79:	89 44 24 08          	mov    %eax,0x8(%esp)
f0104a7d:	89 7c 24 04          	mov    %edi,0x4(%esp)
f0104a81:	8b 45 e4             	mov    -0x1c(%ebp),%eax
f0104a84:	8b 40 5c             	mov    0x5c(%eax),%eax
f0104a87:	89 04 24             	mov    %eax,(%esp)
f0104a8a:	e8 fa c7 ff ff       	call   f0101289 <page_lookup>
f0104a8f:	85 c0                	test   %eax,%eax
f0104a91:	74 31                	je     f0104ac4 <syscall+0x374>
      if ((perm & PTE_W) && ((*srcPte & PTE_W) == 0))
f0104a93:	f6 c3 02             	test   $0x2,%bl
f0104a96:	74 0a                	je     f0104aa2 <syscall+0x352>
f0104a98:	8b 55 e0             	mov    -0x20(%ebp),%edx
f0104a9b:	f6 02 02             	testb  $0x2,(%edx)
f0104a9e:	66 90                	xchg   %ax,%ax
f0104aa0:	74 22                	je     f0104ac4 <syscall+0x374>
        return -E_INVAL;
      return page_insert(dstEnv->env_pgdir, page, dstva, perm);
f0104aa2:	89 5c 24 0c          	mov    %ebx,0xc(%esp)
f0104aa6:	8b 55 18             	mov    0x18(%ebp),%edx
f0104aa9:	89 54 24 08          	mov    %edx,0x8(%esp)
f0104aad:	89 44 24 04          	mov    %eax,0x4(%esp)
f0104ab1:	8b 45 dc             	mov    -0x24(%ebp),%eax
f0104ab4:	8b 40 5c             	mov    0x5c(%eax),%eax
f0104ab7:	89 04 24             	mov    %eax,(%esp)
f0104aba:	e8 d8 c9 ff ff       	call   f0101497 <page_insert>
f0104abf:	e9 f1 02 00 00       	jmp    f0104db5 <syscall+0x665>
f0104ac4:	b8 fd ff ff ff       	mov    $0xfffffffd,%eax
f0104ac9:	e9 e7 02 00 00       	jmp    f0104db5 <syscall+0x665>
f0104ace:	b8 fe ff ff ff       	mov    $0xfffffffe,%eax
f0104ad3:	90                   	nop
f0104ad4:	8d 74 26 00          	lea    0x0(%esi,%eiz,1),%esi
f0104ad8:	e9 d8 02 00 00       	jmp    f0104db5 <syscall+0x665>
//	-E_INVAL if va >= UTOP, or va is not page-aligned.
static int
sys_page_unmap(envid_t envid, void *va)
{
	// Hint: This function is a wrapper around page_remove().
    struct Env *env = NULL;
f0104add:	c7 45 e0 00 00 00 00 	movl   $0x0,-0x20(%ebp)

    // Check if va is valid.
    if (((uint32_t)va >= UTOP)
f0104ae4:	81 ff ff ff bf ee    	cmp    $0xeebfffff,%edi
f0104aea:	77 4a                	ja     f0104b36 <syscall+0x3e6>
f0104aec:	f7 c7 ff 0f 00 00    	test   $0xfff,%edi
f0104af2:	75 42                	jne    f0104b36 <syscall+0x3e6>
        || ((uint32_t)va & 0xFFF))
        return -E_INVAL;

    // Check if request is from a privileged environment.
    if (envid2env(envid, &env, 1))
f0104af4:	c7 44 24 08 01 00 00 	movl   $0x1,0x8(%esp)
f0104afb:	00 
f0104afc:	8d 45 e0             	lea    -0x20(%ebp),%eax
f0104aff:	89 44 24 04          	mov    %eax,0x4(%esp)
f0104b03:	89 34 24             	mov    %esi,(%esp)
f0104b06:	e8 75 e5 ff ff       	call   f0103080 <envid2env>
f0104b0b:	89 c2                	mov    %eax,%edx
f0104b0d:	b8 fe ff ff ff       	mov    $0xfffffffe,%eax
f0104b12:	85 d2                	test   %edx,%edx
f0104b14:	0f 85 9b 02 00 00    	jne    f0104db5 <syscall+0x665>
      return -E_BAD_ENV;

    page_remove(env->env_pgdir, va);
f0104b1a:	89 7c 24 04          	mov    %edi,0x4(%esp)
f0104b1e:	8b 45 e0             	mov    -0x20(%ebp),%eax
f0104b21:	8b 40 5c             	mov    0x5c(%eax),%eax
f0104b24:	89 04 24             	mov    %eax,(%esp)
f0104b27:	e8 13 c9 ff ff       	call   f010143f <page_remove>
f0104b2c:	b8 00 00 00 00       	mov    $0x0,%eax
f0104b31:	e9 7f 02 00 00       	jmp    f0104db5 <syscall+0x665>
f0104b36:	b8 fd ff ff ff       	mov    $0xfffffffd,%eax
f0104b3b:	e9 75 02 00 00       	jmp    f0104db5 <syscall+0x665>
//	-E_BAD_ENV if environment envid doesn't currently exist,
//		or the caller doesn't have permission to change envid.
static int
sys_env_set_pgfault_upcall(envid_t envid, void *func)
{
    struct Env *env = NULL;
f0104b40:	c7 45 e0 00 00 00 00 	movl   $0x0,-0x20(%ebp)

    if (!envid2env(envid, &env, 1)) {
f0104b47:	c7 44 24 08 01 00 00 	movl   $0x1,0x8(%esp)
f0104b4e:	00 
f0104b4f:	8d 45 e0             	lea    -0x20(%ebp),%eax
f0104b52:	89 44 24 04          	mov    %eax,0x4(%esp)
f0104b56:	89 34 24             	mov    %esi,(%esp)
f0104b59:	e8 22 e5 ff ff       	call   f0103080 <envid2env>
f0104b5e:	89 c2                	mov    %eax,%edx
f0104b60:	b8 fe ff ff ff       	mov    $0xfffffffe,%eax
f0104b65:	85 d2                	test   %edx,%edx
f0104b67:	0f 85 48 02 00 00    	jne    f0104db5 <syscall+0x665>
        env->env_pgfault_upcall = func;
f0104b6d:	8b 45 e0             	mov    -0x20(%ebp),%eax
f0104b70:	89 78 64             	mov    %edi,0x64(%eax)
f0104b73:	b8 00 00 00 00       	mov    $0x0,%eax
f0104b78:	e9 38 02 00 00       	jmp    f0104db5 <syscall+0x665>
// Return < 0 on error.  Errors are:
//	-E_INVAL if dstva < UTOP but dstva is not page-aligned.
static int
sys_ipc_recv(void *dstva)
{
  if (((uint32_t)dstva < UTOP) && ((uint32_t)dstva%PGSIZE != 0))
f0104b7d:	81 fe ff ff bf ee    	cmp    $0xeebfffff,%esi
f0104b83:	77 11                	ja     f0104b96 <syscall+0x446>
f0104b85:	b8 fd ff ff ff       	mov    $0xfffffffd,%eax
f0104b8a:	f7 c6 ff 0f 00 00    	test   $0xfff,%esi
f0104b90:	0f 85 1f 02 00 00    	jne    f0104db5 <syscall+0x665>
    return -E_INVAL;

  curenv->env_ipc_recving = 1;
f0104b96:	a1 60 f2 2c f0       	mov    0xf02cf260,%eax
f0104b9b:	c7 40 68 01 00 00 00 	movl   $0x1,0x68(%eax)
  curenv->env_ipc_dstva   = dstva;
f0104ba2:	a1 60 f2 2c f0       	mov    0xf02cf260,%eax
f0104ba7:	89 70 6c             	mov    %esi,0x6c(%eax)
  curenv->env_status      = ENV_NOT_RUNNABLE;
f0104baa:	a1 60 f2 2c f0       	mov    0xf02cf260,%eax
f0104baf:	c7 40 54 02 00 00 00 	movl   $0x2,0x54(%eax)
f0104bb6:	b8 00 00 00 00       	mov    $0x0,%eax
f0104bbb:	e9 f5 01 00 00       	jmp    f0104db5 <syscall+0x665>
//	-E_NO_MEM if there's not enough memory to map srcva in envid's
//		address space.
static int
sys_ipc_try_send(envid_t envid, uint32_t value, void *srcva, unsigned perm)
{
  struct Env *env = NULL;
f0104bc0:	c7 45 e0 00 00 00 00 	movl   $0x0,-0x20(%ebp)
  pte_t *pte      = NULL;
f0104bc7:	c7 45 dc 00 00 00 00 	movl   $0x0,-0x24(%ebp)
  struct Page *pg = NULL;

  if (envid2env(envid, &env, 0)) {
f0104bce:	c7 44 24 08 00 00 00 	movl   $0x0,0x8(%esp)
f0104bd5:	00 
f0104bd6:	8d 45 e0             	lea    -0x20(%ebp),%eax
f0104bd9:	89 44 24 04          	mov    %eax,0x4(%esp)
f0104bdd:	89 34 24             	mov    %esi,(%esp)
f0104be0:	e8 9b e4 ff ff       	call   f0103080 <envid2env>
f0104be5:	89 c2                	mov    %eax,%edx
f0104be7:	b8 fe ff ff ff       	mov    $0xfffffffe,%eax
f0104bec:	85 d2                	test   %edx,%edx
f0104bee:	0f 85 c1 01 00 00    	jne    f0104db5 <syscall+0x665>
    return -E_BAD_ENV;
  }

  if (env->env_ipc_recving != 1) {
f0104bf4:	b0 f9                	mov    $0xf9,%al
f0104bf6:	8b 55 e0             	mov    -0x20(%ebp),%edx
f0104bf9:	83 7a 68 01          	cmpl   $0x1,0x68(%edx)
f0104bfd:	0f 85 b2 01 00 00    	jne    f0104db5 <syscall+0x665>
    return -E_IPC_NOT_RECV;
  }

  if (((uint32_t)srcva < UTOP) && 
f0104c03:	81 7d 14 ff ff bf ee 	cmpl   $0xeebfffff,0x14(%ebp)
f0104c0a:	0f 87 a9 00 00 00    	ja     f0104cb9 <syscall+0x569>
f0104c10:	f7 45 14 ff 0f 00 00 	testl  $0xfff,0x14(%ebp)
f0104c17:	0f 85 a5 01 00 00    	jne    f0104dc2 <syscall+0x672>
    ((uint32_t)srcva%PGSIZE == 0) &&
    (pg=page_lookup(curenv->env_pgdir, srcva, &pte)) &&
f0104c1d:	8d 45 dc             	lea    -0x24(%ebp),%eax
f0104c20:	89 44 24 08          	mov    %eax,0x8(%esp)
f0104c24:	8b 45 14             	mov    0x14(%ebp),%eax
f0104c27:	89 44 24 04          	mov    %eax,0x4(%esp)
f0104c2b:	a1 60 f2 2c f0       	mov    0xf02cf260,%eax
f0104c30:	8b 40 5c             	mov    0x5c(%eax),%eax
f0104c33:	89 04 24             	mov    %eax,(%esp)
f0104c36:	e8 4e c6 ff ff       	call   f0101289 <page_lookup>

  if (env->env_ipc_recving != 1) {
    return -E_IPC_NOT_RECV;
  }

  if (((uint32_t)srcva < UTOP) && 
f0104c3b:	85 c0                	test   %eax,%eax
f0104c3d:	0f 84 7f 01 00 00    	je     f0104dc2 <syscall+0x672>
f0104c43:	8b 4d 14             	mov    0x14(%ebp),%ecx
f0104c46:	c1 e9 0c             	shr    $0xc,%ecx
f0104c49:	81 e1 ff 03 00 00    	and    $0x3ff,%ecx
f0104c4f:	8b 5d 18             	mov    0x18(%ebp),%ebx
f0104c52:	81 f3 07 0e 00 00    	xor    $0xe07,%ebx
f0104c58:	8b 55 dc             	mov    -0x24(%ebp),%edx
f0104c5b:	85 1c 8a             	test   %ebx,(%edx,%ecx,4)
f0104c5e:	74 0a                	je     f0104c6a <syscall+0x51a>
f0104c60:	83 7d 18 00          	cmpl   $0x0,0x18(%ebp)
f0104c64:	0f 85 58 01 00 00    	jne    f0104dc2 <syscall+0x672>
    ((uint32_t)srcva%PGSIZE == 0) &&
    (pg=page_lookup(curenv->env_pgdir, srcva, &pte)) &&
    (((pte[PTX(srcva)]&PTE_USER)==(pte[PTX(srcva)]&perm)) || (perm==0))) {
    if ((uint32_t)env->env_ipc_dstva < UTOP) {
f0104c6a:	8b 55 e0             	mov    -0x20(%ebp),%edx
f0104c6d:	8b 4a 6c             	mov    0x6c(%edx),%ecx
f0104c70:	81 f9 ff ff bf ee    	cmp    $0xeebfffff,%ecx
f0104c76:	77 3a                	ja     f0104cb2 <syscall+0x562>
      if (page_insert(env->env_pgdir, pg, env->env_ipc_dstva, perm)) {
f0104c78:	8b 5d 18             	mov    0x18(%ebp),%ebx
f0104c7b:	89 5c 24 0c          	mov    %ebx,0xc(%esp)
f0104c7f:	89 4c 24 08          	mov    %ecx,0x8(%esp)
f0104c83:	89 44 24 04          	mov    %eax,0x4(%esp)
f0104c87:	8b 42 5c             	mov    0x5c(%edx),%eax
f0104c8a:	89 04 24             	mov    %eax,(%esp)
f0104c8d:	e8 05 c8 ff ff       	call   f0101497 <page_insert>
f0104c92:	85 c0                	test   %eax,%eax
f0104c94:	74 14                	je     f0104caa <syscall+0x55a>
        env->env_ipc_perm   = 0;
f0104c96:	8b 45 e0             	mov    -0x20(%ebp),%eax
f0104c99:	c7 40 78 00 00 00 00 	movl   $0x0,0x78(%eax)
f0104ca0:	b8 fc ff ff ff       	mov    $0xfffffffc,%eax
f0104ca5:	e9 0b 01 00 00       	jmp    f0104db5 <syscall+0x665>
        return -E_NO_MEM;
      }
      env->env_ipc_perm   = perm;
f0104caa:	8b 45 e0             	mov    -0x20(%ebp),%eax
f0104cad:	89 58 78             	mov    %ebx,0x78(%eax)
f0104cb0:	eb 07                	jmp    f0104cb9 <syscall+0x569>
    } else {
      env->env_ipc_perm   = 0;
f0104cb2:	c7 42 78 00 00 00 00 	movl   $0x0,0x78(%edx)
    }
  } else if ((uint32_t)srcva < UTOP) {
    env->env_ipc_perm   = 0;
    return -E_INVAL;
  }
  env->env_ipc_recving    = 0;
f0104cb9:	8b 45 e0             	mov    -0x20(%ebp),%eax
f0104cbc:	c7 40 68 00 00 00 00 	movl   $0x0,0x68(%eax)
  env->env_ipc_dstva      = NULL;
f0104cc3:	8b 45 e0             	mov    -0x20(%ebp),%eax
f0104cc6:	c7 40 6c 00 00 00 00 	movl   $0x0,0x6c(%eax)
  env->env_ipc_from       = curenv->env_id;
f0104ccd:	a1 60 f2 2c f0       	mov    0xf02cf260,%eax
f0104cd2:	8b 50 4c             	mov    0x4c(%eax),%edx
f0104cd5:	8b 45 e0             	mov    -0x20(%ebp),%eax
f0104cd8:	89 50 74             	mov    %edx,0x74(%eax)
  env->env_ipc_value      = value;
f0104cdb:	8b 45 e0             	mov    -0x20(%ebp),%eax
f0104cde:	89 78 70             	mov    %edi,0x70(%eax)
  env->env_status         = ENV_RUNNABLE;
f0104ce1:	8b 45 e0             	mov    -0x20(%ebp),%eax
f0104ce4:	c7 40 54 01 00 00 00 	movl   $0x1,0x54(%eax)
f0104ceb:	b8 00 00 00 00       	mov    $0x0,%eax
f0104cf0:	e9 c0 00 00 00       	jmp    f0104db5 <syscall+0x665>
    case SYS_ipc_recv:
      return sys_ipc_recv((void *)a1);
    case SYS_ipc_try_send:
      return sys_ipc_try_send((envid_t)a1, (uint32_t)a2, (void *)a3, a4);
    case SYS_env_set_trapframe:
      return sys_env_set_trapframe((envid_t)a1, (struct Trapframe *)a2);
f0104cf5:	89 fb                	mov    %edi,%ebx
sys_env_set_trapframe(envid_t envid, struct Trapframe *tf)
{
	// LAB 5: Your code here.
	// Remember to check whether the user has supplied us with a good
	// address!
    struct Env *e   = NULL;
f0104cf7:	c7 45 dc 00 00 00 00 	movl   $0x0,-0x24(%ebp)
    int r   = 0;
    if (tf==NULL||(((uint32_t)tf)>USTACKTOP))
f0104cfe:	85 ff                	test   %edi,%edi
f0104d00:	74 08                	je     f0104d0a <syscall+0x5ba>
f0104d02:	81 ff 00 e0 bf ee    	cmp    $0xeebfe000,%edi
f0104d08:	76 0a                	jbe    f0104d14 <syscall+0x5c4>
f0104d0a:	b8 fd ff ff ff       	mov    $0xfffffffd,%eax
f0104d0f:	e9 a1 00 00 00       	jmp    f0104db5 <syscall+0x665>
        return -E_INVAL;

    if ((r=envid2env(envid, &e, 1)<0))
f0104d14:	c7 44 24 08 01 00 00 	movl   $0x1,0x8(%esp)
f0104d1b:	00 
f0104d1c:	8d 45 dc             	lea    -0x24(%ebp),%eax
f0104d1f:	89 44 24 04          	mov    %eax,0x4(%esp)
f0104d23:	89 34 24             	mov    %esi,(%esp)
f0104d26:	e8 55 e3 ff ff       	call   f0103080 <envid2env>
f0104d2b:	c1 e8 1f             	shr    $0x1f,%eax
f0104d2e:	85 c0                	test   %eax,%eax
f0104d30:	0f 85 7f 00 00 00    	jne    f0104db5 <syscall+0x665>
        return r;

    e->env_tf   = *tf;
f0104d36:	8b 55 dc             	mov    -0x24(%ebp),%edx
f0104d39:	b9 11 00 00 00       	mov    $0x11,%ecx
f0104d3e:	89 d7                	mov    %edx,%edi
f0104d40:	89 de                	mov    %ebx,%esi
f0104d42:	f3 a5                	rep movsl %ds:(%esi),%es:(%edi)
f0104d44:	eb 6f                	jmp    f0104db5 <syscall+0x665>
// Return the current time.
static int
sys_time_msec(void) 
{
	// LAB 6: Your code here.
    return time_msec();
f0104d46:	e8 18 19 00 00       	call   f0106663 <time_msec>
    case SYS_ipc_try_send:
      return sys_ipc_try_send((envid_t)a1, (uint32_t)a2, (void *)a3, a4);
    case SYS_env_set_trapframe:
      return sys_env_set_trapframe((envid_t)a1, (struct Trapframe *)a2);
    case SYS_time_msec:
      return sys_time_msec();
f0104d4b:	eb 68                	jmp    f0104db5 <syscall+0x665>
    case SYS_ns_send:
      return sys_ns_send((void *)a1, (int)a2);
f0104d4d:	89 f0                	mov    %esi,%eax
 **/

static int
sys_ns_send(void *pkt, int len) {
    int r=0;
    if (!pkt)
f0104d4f:	85 f6                	test   %esi,%esi
f0104d51:	74 19                	je     f0104d6c <syscall+0x61c>
        return -E_INVAL;
    
    if ((((uint32_t)pkt)+len)>USTACKTOP)
f0104d53:	8d 34 37             	lea    (%edi,%esi,1),%esi
f0104d56:	81 fe 00 e0 bf ee    	cmp    $0xeebfe000,%esi
f0104d5c:	77 0e                	ja     f0104d6c <syscall+0x61c>
        return -E_INVAL;

    return e100_ns_send(pkt, len);
f0104d5e:	89 7c 24 04          	mov    %edi,0x4(%esp)
f0104d62:	89 04 24             	mov    %eax,(%esp)
f0104d65:	e8 b6 0f 00 00       	call   f0105d20 <e100_ns_send>
f0104d6a:	eb 49                	jmp    f0104db5 <syscall+0x665>
f0104d6c:	b8 fd ff ff ff       	mov    $0xfffffffd,%eax
f0104d71:	eb 42                	jmp    f0104db5 <syscall+0x665>
    case SYS_time_msec:
      return sys_time_msec();
    case SYS_ns_send:
      return sys_ns_send((void *)a1, (int)a2);
    case SYS_ns_recv:
      return sys_ns_recv((void *)a1, (int)a2);
f0104d73:	89 f0                	mov    %esi,%eax
 * received packet.
 **/

static int
sys_ns_recv(void *pkt, int len) {
    if (!pkt)
f0104d75:	85 f6                	test   %esi,%esi
f0104d77:	74 19                	je     f0104d92 <syscall+0x642>
        return -E_INVAL;
    
    if ((((uint32_t)pkt)+len)>USTACKTOP)
f0104d79:	8d 34 37             	lea    (%edi,%esi,1),%esi
f0104d7c:	81 fe 00 e0 bf ee    	cmp    $0xeebfe000,%esi
f0104d82:	77 0e                	ja     f0104d92 <syscall+0x642>
        return -E_INVAL;

    return e100_ns_recv(pkt, len);
f0104d84:	89 7c 24 04          	mov    %edi,0x4(%esp)
f0104d88:	89 04 24             	mov    %eax,(%esp)
f0104d8b:	e8 00 10 00 00       	call   f0105d90 <e100_ns_recv>
f0104d90:	eb 23                	jmp    f0104db5 <syscall+0x665>
f0104d92:	b8 fd ff ff ff       	mov    $0xfffffffd,%eax
f0104d97:	eb 1c                	jmp    f0104db5 <syscall+0x665>
    case SYS_ns_send:
      return sys_ns_send((void *)a1, (int)a2);
    case SYS_ns_recv:
      return sys_ns_recv((void *)a1, (int)a2);
  }
	panic("syscall not implemented");
f0104d99:	c7 44 24 08 f6 7d 10 	movl   $0xf0107df6,0x8(%esp)
f0104da0:	f0 
f0104da1:	c7 44 24 04 eb 01 00 	movl   $0x1eb,0x4(%esp)
f0104da8:	00 
f0104da9:	c7 04 24 e7 7d 10 f0 	movl   $0xf0107de7,(%esp)
f0104db0:	e8 d0 b2 ff ff       	call   f0100085 <_panic>
}
f0104db5:	8b 5d f4             	mov    -0xc(%ebp),%ebx
f0104db8:	8b 75 f8             	mov    -0x8(%ebp),%esi
f0104dbb:	8b 7d fc             	mov    -0x4(%ebp),%edi
f0104dbe:	89 ec                	mov    %ebp,%esp
f0104dc0:	5d                   	pop    %ebp
f0104dc1:	c3                   	ret    
      env->env_ipc_perm   = perm;
    } else {
      env->env_ipc_perm   = 0;
    }
  } else if ((uint32_t)srcva < UTOP) {
    env->env_ipc_perm   = 0;
f0104dc2:	8b 45 e0             	mov    -0x20(%ebp),%eax
f0104dc5:	c7 40 78 00 00 00 00 	movl   $0x0,0x78(%eax)
f0104dcc:	b8 fd ff ff ff       	mov    $0xfffffffd,%eax
f0104dd1:	eb e2                	jmp    f0104db5 <syscall+0x665>
	...

f0104de0 <stab_binsearch>:
//	will exit setting left = 118, right = 554.
//
static void
stab_binsearch(const struct Stab *stabs, int *region_left, int *region_right,
	       int type, uintptr_t addr)
{
f0104de0:	55                   	push   %ebp
f0104de1:	89 e5                	mov    %esp,%ebp
f0104de3:	57                   	push   %edi
f0104de4:	56                   	push   %esi
f0104de5:	53                   	push   %ebx
f0104de6:	83 ec 14             	sub    $0x14,%esp
f0104de9:	89 45 f0             	mov    %eax,-0x10(%ebp)
f0104dec:	89 55 e8             	mov    %edx,-0x18(%ebp)
f0104def:	89 4d e0             	mov    %ecx,-0x20(%ebp)
f0104df2:	8b 75 08             	mov    0x8(%ebp),%esi
	int l = *region_left, r = *region_right, any_matches = 0;
f0104df5:	8b 1a                	mov    (%edx),%ebx
f0104df7:	8b 01                	mov    (%ecx),%eax
f0104df9:	89 45 ec             	mov    %eax,-0x14(%ebp)
	
	while (l <= r) {
f0104dfc:	39 c3                	cmp    %eax,%ebx
f0104dfe:	0f 8f 9c 00 00 00    	jg     f0104ea0 <stab_binsearch+0xc0>
f0104e04:	c7 45 e4 00 00 00 00 	movl   $0x0,-0x1c(%ebp)
		int true_m = (l + r) / 2, m = true_m;
f0104e0b:	8b 45 ec             	mov    -0x14(%ebp),%eax
f0104e0e:	01 d8                	add    %ebx,%eax
f0104e10:	89 c7                	mov    %eax,%edi
f0104e12:	c1 ef 1f             	shr    $0x1f,%edi
f0104e15:	01 c7                	add    %eax,%edi
f0104e17:	d1 ff                	sar    %edi
		
		// search for earliest stab with right type
		while (m >= l && stabs[m].n_type != type)
f0104e19:	39 df                	cmp    %ebx,%edi
f0104e1b:	7c 33                	jl     f0104e50 <stab_binsearch+0x70>
f0104e1d:	8d 04 7f             	lea    (%edi,%edi,2),%eax
f0104e20:	8b 55 f0             	mov    -0x10(%ebp),%edx
f0104e23:	0f b6 44 82 04       	movzbl 0x4(%edx,%eax,4),%eax
f0104e28:	39 f0                	cmp    %esi,%eax
f0104e2a:	0f 84 bc 00 00 00    	je     f0104eec <stab_binsearch+0x10c>
f0104e30:	8d 44 7f fd          	lea    -0x3(%edi,%edi,2),%eax
f0104e34:	8d 54 82 04          	lea    0x4(%edx,%eax,4),%edx
f0104e38:	89 f8                	mov    %edi,%eax
			m--;
f0104e3a:	83 e8 01             	sub    $0x1,%eax
	
	while (l <= r) {
		int true_m = (l + r) / 2, m = true_m;
		
		// search for earliest stab with right type
		while (m >= l && stabs[m].n_type != type)
f0104e3d:	39 d8                	cmp    %ebx,%eax
f0104e3f:	7c 0f                	jl     f0104e50 <stab_binsearch+0x70>
f0104e41:	0f b6 0a             	movzbl (%edx),%ecx
f0104e44:	83 ea 0c             	sub    $0xc,%edx
f0104e47:	39 f1                	cmp    %esi,%ecx
f0104e49:	75 ef                	jne    f0104e3a <stab_binsearch+0x5a>
f0104e4b:	e9 9e 00 00 00       	jmp    f0104eee <stab_binsearch+0x10e>
			m--;
		if (m < l) {	// no match in [l, m]
			l = true_m + 1;
f0104e50:	8d 5f 01             	lea    0x1(%edi),%ebx
			continue;
f0104e53:	eb 3c                	jmp    f0104e91 <stab_binsearch+0xb1>
		}

		// actual binary search
		any_matches = 1;
		if (stabs[m].n_value < addr) {
			*region_left = m;
f0104e55:	8b 4d e8             	mov    -0x18(%ebp),%ecx
f0104e58:	89 01                	mov    %eax,(%ecx)
			l = true_m + 1;
f0104e5a:	8d 5f 01             	lea    0x1(%edi),%ebx
f0104e5d:	c7 45 e4 01 00 00 00 	movl   $0x1,-0x1c(%ebp)
f0104e64:	eb 2b                	jmp    f0104e91 <stab_binsearch+0xb1>
		} else if (stabs[m].n_value > addr) {
f0104e66:	3b 55 0c             	cmp    0xc(%ebp),%edx
f0104e69:	76 14                	jbe    f0104e7f <stab_binsearch+0x9f>
			*region_right = m - 1;
f0104e6b:	83 e8 01             	sub    $0x1,%eax
f0104e6e:	89 45 ec             	mov    %eax,-0x14(%ebp)
f0104e71:	8b 55 e0             	mov    -0x20(%ebp),%edx
f0104e74:	89 02                	mov    %eax,(%edx)
f0104e76:	c7 45 e4 01 00 00 00 	movl   $0x1,-0x1c(%ebp)
f0104e7d:	eb 12                	jmp    f0104e91 <stab_binsearch+0xb1>
			r = m - 1;
		} else {
			// exact match for 'addr', but continue loop to find
			// *region_right
			*region_left = m;
f0104e7f:	8b 4d e8             	mov    -0x18(%ebp),%ecx
f0104e82:	89 01                	mov    %eax,(%ecx)
			l = m;
			addr++;
f0104e84:	83 45 0c 01          	addl   $0x1,0xc(%ebp)
f0104e88:	89 c3                	mov    %eax,%ebx
f0104e8a:	c7 45 e4 01 00 00 00 	movl   $0x1,-0x1c(%ebp)
stab_binsearch(const struct Stab *stabs, int *region_left, int *region_right,
	       int type, uintptr_t addr)
{
	int l = *region_left, r = *region_right, any_matches = 0;
	
	while (l <= r) {
f0104e91:	39 5d ec             	cmp    %ebx,-0x14(%ebp)
f0104e94:	0f 8d 71 ff ff ff    	jge    f0104e0b <stab_binsearch+0x2b>
			l = m;
			addr++;
		}
	}

	if (!any_matches)
f0104e9a:	83 7d e4 00          	cmpl   $0x0,-0x1c(%ebp)
f0104e9e:	75 0f                	jne    f0104eaf <stab_binsearch+0xcf>
		*region_right = *region_left - 1;
f0104ea0:	8b 5d e8             	mov    -0x18(%ebp),%ebx
f0104ea3:	8b 03                	mov    (%ebx),%eax
f0104ea5:	83 e8 01             	sub    $0x1,%eax
f0104ea8:	8b 55 e0             	mov    -0x20(%ebp),%edx
f0104eab:	89 02                	mov    %eax,(%edx)
f0104ead:	eb 57                	jmp    f0104f06 <stab_binsearch+0x126>
	else {
		// find rightmost region containing 'addr'
		for (l = *region_right;
f0104eaf:	8b 4d e0             	mov    -0x20(%ebp),%ecx
f0104eb2:	8b 01                	mov    (%ecx),%eax
		     l > *region_left && stabs[l].n_type != type;
f0104eb4:	8b 5d e8             	mov    -0x18(%ebp),%ebx
f0104eb7:	8b 0b                	mov    (%ebx),%ecx

	if (!any_matches)
		*region_right = *region_left - 1;
	else {
		// find rightmost region containing 'addr'
		for (l = *region_right;
f0104eb9:	39 c1                	cmp    %eax,%ecx
f0104ebb:	7d 28                	jge    f0104ee5 <stab_binsearch+0x105>
		     l > *region_left && stabs[l].n_type != type;
f0104ebd:	8d 14 40             	lea    (%eax,%eax,2),%edx
f0104ec0:	8b 5d f0             	mov    -0x10(%ebp),%ebx
f0104ec3:	0f b6 54 93 04       	movzbl 0x4(%ebx,%edx,4),%edx
f0104ec8:	39 f2                	cmp    %esi,%edx
f0104eca:	74 19                	je     f0104ee5 <stab_binsearch+0x105>
f0104ecc:	8d 54 40 fd          	lea    -0x3(%eax,%eax,2),%edx
f0104ed0:	8d 54 93 04          	lea    0x4(%ebx,%edx,4),%edx
		     l--)
f0104ed4:	83 e8 01             	sub    $0x1,%eax

	if (!any_matches)
		*region_right = *region_left - 1;
	else {
		// find rightmost region containing 'addr'
		for (l = *region_right;
f0104ed7:	39 c1                	cmp    %eax,%ecx
f0104ed9:	7d 0a                	jge    f0104ee5 <stab_binsearch+0x105>
		     l > *region_left && stabs[l].n_type != type;
f0104edb:	0f b6 1a             	movzbl (%edx),%ebx
f0104ede:	83 ea 0c             	sub    $0xc,%edx

	if (!any_matches)
		*region_right = *region_left - 1;
	else {
		// find rightmost region containing 'addr'
		for (l = *region_right;
f0104ee1:	39 f3                	cmp    %esi,%ebx
f0104ee3:	75 ef                	jne    f0104ed4 <stab_binsearch+0xf4>
		     l > *region_left && stabs[l].n_type != type;
		     l--)
			/* do nothing */;
		*region_left = l;
f0104ee5:	8b 55 e8             	mov    -0x18(%ebp),%edx
f0104ee8:	89 02                	mov    %eax,(%edx)
f0104eea:	eb 1a                	jmp    f0104f06 <stab_binsearch+0x126>
	}
}
f0104eec:	89 f8                	mov    %edi,%eax
			continue;
		}

		// actual binary search
		any_matches = 1;
		if (stabs[m].n_value < addr) {
f0104eee:	8d 14 40             	lea    (%eax,%eax,2),%edx
f0104ef1:	8b 4d f0             	mov    -0x10(%ebp),%ecx
f0104ef4:	8b 54 91 08          	mov    0x8(%ecx,%edx,4),%edx
f0104ef8:	3b 55 0c             	cmp    0xc(%ebp),%edx
f0104efb:	0f 82 54 ff ff ff    	jb     f0104e55 <stab_binsearch+0x75>
f0104f01:	e9 60 ff ff ff       	jmp    f0104e66 <stab_binsearch+0x86>
		     l > *region_left && stabs[l].n_type != type;
		     l--)
			/* do nothing */;
		*region_left = l;
	}
}
f0104f06:	83 c4 14             	add    $0x14,%esp
f0104f09:	5b                   	pop    %ebx
f0104f0a:	5e                   	pop    %esi
f0104f0b:	5f                   	pop    %edi
f0104f0c:	5d                   	pop    %ebp
f0104f0d:	c3                   	ret    

f0104f0e <debuginfo_eip>:
//	negative if not.  But even if it returns negative it has stored some
//	information into '*info'.
//
int
debuginfo_eip(uintptr_t addr, struct Eipdebuginfo *info)
{
f0104f0e:	55                   	push   %ebp
f0104f0f:	89 e5                	mov    %esp,%ebp
f0104f11:	83 ec 58             	sub    $0x58,%esp
f0104f14:	89 5d f4             	mov    %ebx,-0xc(%ebp)
f0104f17:	89 75 f8             	mov    %esi,-0x8(%ebp)
f0104f1a:	89 7d fc             	mov    %edi,-0x4(%ebp)
f0104f1d:	8b 75 08             	mov    0x8(%ebp),%esi
f0104f20:	8b 5d 0c             	mov    0xc(%ebp),%ebx
	int lfile, rfile, lfun, rfun, lline, rline;
	int lfind	= 0;
	int lfstart;

	// Initialize *info
	info->eip_file = "<unknown>";
f0104f23:	c7 03 54 7e 10 f0    	movl   $0xf0107e54,(%ebx)
	info->eip_line = 0;
f0104f29:	c7 43 04 00 00 00 00 	movl   $0x0,0x4(%ebx)
	info->eip_fn_name = "<unknown>";
f0104f30:	c7 43 08 54 7e 10 f0 	movl   $0xf0107e54,0x8(%ebx)
	info->eip_fn_namelen = 9;
f0104f37:	c7 43 0c 09 00 00 00 	movl   $0x9,0xc(%ebx)
	info->eip_fn_addr = addr;
f0104f3e:	89 73 10             	mov    %esi,0x10(%ebx)
	info->eip_fn_narg = 0;
f0104f41:	c7 43 14 00 00 00 00 	movl   $0x0,0x14(%ebx)
	// Find the relevant set of stabs
	if (addr >= ULIM) {
f0104f48:	81 fe ff ff 7f ef    	cmp    $0xef7fffff,%esi
f0104f4e:	76 1f                	jbe    f0104f6f <debuginfo_eip+0x61>
f0104f50:	bf 62 5e 11 f0       	mov    $0xf0115e62,%edi
f0104f55:	c7 45 c4 b1 22 11 f0 	movl   $0xf01122b1,-0x3c(%ebp)
f0104f5c:	c7 45 bc b0 22 11 f0 	movl   $0xf01122b0,-0x44(%ebp)
f0104f63:	c7 45 c0 28 84 10 f0 	movl   $0xf0108428,-0x40(%ebp)
f0104f6a:	e9 a0 00 00 00       	jmp    f010500f <debuginfo_eip+0x101>
		const struct UserStabData *usd = (const struct UserStabData *) USTABDATA;

		// Make sure this memory is valid.
		// Return -1 if it is not.  Hint: Call user_mem_check.
		// LAB 3: Your code here.
        if (user_mem_check(curenv, usd, sizeof(struct UserStabData), PTE_U))
f0104f6f:	c7 44 24 0c 04 00 00 	movl   $0x4,0xc(%esp)
f0104f76:	00 
f0104f77:	c7 44 24 08 10 00 00 	movl   $0x10,0x8(%esp)
f0104f7e:	00 
f0104f7f:	c7 44 24 04 00 00 20 	movl   $0x200000,0x4(%esp)
f0104f86:	00 
f0104f87:	a1 60 f2 2c f0       	mov    0xf02cf260,%eax
f0104f8c:	89 04 24             	mov    %eax,(%esp)
f0104f8f:	e8 72 c3 ff ff       	call   f0101306 <user_mem_check>
f0104f94:	85 c0                	test   %eax,%eax
f0104f96:	0f 85 31 02 00 00    	jne    f01051cd <debuginfo_eip+0x2bf>
            return -1;

		stabs = usd->stabs;
f0104f9c:	b8 00 00 20 00       	mov    $0x200000,%eax
f0104fa1:	8b 10                	mov    (%eax),%edx
f0104fa3:	89 55 c0             	mov    %edx,-0x40(%ebp)
		stab_end = usd->stab_end;
f0104fa6:	8b 48 04             	mov    0x4(%eax),%ecx
f0104fa9:	89 4d bc             	mov    %ecx,-0x44(%ebp)
		stabstr = usd->stabstr;
f0104fac:	8b 50 08             	mov    0x8(%eax),%edx
f0104faf:	89 55 c4             	mov    %edx,-0x3c(%ebp)
		stabstr_end = usd->stabstr_end;
f0104fb2:	8b 78 0c             	mov    0xc(%eax),%edi

        if (user_mem_check(curenv, stabs, (uint32_t)stab_end-(uint32_t)stabs, PTE_U)
            || user_mem_check(curenv, stabstr, (uint32_t)stabstr_end-(uint32_t)stabstr, PTE_U))
f0104fb5:	c7 44 24 0c 04 00 00 	movl   $0x4,0xc(%esp)
f0104fbc:	00 
f0104fbd:	89 c8                	mov    %ecx,%eax
f0104fbf:	2b 45 c0             	sub    -0x40(%ebp),%eax
f0104fc2:	89 44 24 08          	mov    %eax,0x8(%esp)
f0104fc6:	8b 4d c0             	mov    -0x40(%ebp),%ecx
f0104fc9:	89 4c 24 04          	mov    %ecx,0x4(%esp)
f0104fcd:	a1 60 f2 2c f0       	mov    0xf02cf260,%eax
f0104fd2:	89 04 24             	mov    %eax,(%esp)
f0104fd5:	e8 2c c3 ff ff       	call   f0101306 <user_mem_check>
		stabs = usd->stabs;
		stab_end = usd->stab_end;
		stabstr = usd->stabstr;
		stabstr_end = usd->stabstr_end;

        if (user_mem_check(curenv, stabs, (uint32_t)stab_end-(uint32_t)stabs, PTE_U)
f0104fda:	85 c0                	test   %eax,%eax
f0104fdc:	0f 85 eb 01 00 00    	jne    f01051cd <debuginfo_eip+0x2bf>
            || user_mem_check(curenv, stabstr, (uint32_t)stabstr_end-(uint32_t)stabstr, PTE_U))
f0104fe2:	c7 44 24 0c 04 00 00 	movl   $0x4,0xc(%esp)
f0104fe9:	00 
f0104fea:	89 f8                	mov    %edi,%eax
f0104fec:	2b 45 c4             	sub    -0x3c(%ebp),%eax
f0104fef:	89 44 24 08          	mov    %eax,0x8(%esp)
f0104ff3:	8b 45 c4             	mov    -0x3c(%ebp),%eax
f0104ff6:	89 44 24 04          	mov    %eax,0x4(%esp)
f0104ffa:	a1 60 f2 2c f0       	mov    0xf02cf260,%eax
f0104fff:	89 04 24             	mov    %eax,(%esp)
f0105002:	e8 ff c2 ff ff       	call   f0101306 <user_mem_check>
		stabs = usd->stabs;
		stab_end = usd->stab_end;
		stabstr = usd->stabstr;
		stabstr_end = usd->stabstr_end;

        if (user_mem_check(curenv, stabs, (uint32_t)stab_end-(uint32_t)stabs, PTE_U)
f0105007:	85 c0                	test   %eax,%eax
f0105009:	0f 85 be 01 00 00    	jne    f01051cd <debuginfo_eip+0x2bf>
		// Make sure the STABS and string table memory is valid.
		// LAB 3: Your code here.
	}

	// String table validity checks
	if (stabstr_end <= stabstr || stabstr_end[-1] != 0)
f010500f:	39 7d c4             	cmp    %edi,-0x3c(%ebp)
f0105012:	0f 83 b5 01 00 00    	jae    f01051cd <debuginfo_eip+0x2bf>
f0105018:	80 7f ff 00          	cmpb   $0x0,-0x1(%edi)
f010501c:	8d 74 26 00          	lea    0x0(%esi,%eiz,1),%esi
f0105020:	0f 85 a7 01 00 00    	jne    f01051cd <debuginfo_eip+0x2bf>
	// 'eip'.  First, we find the basic source file containing 'eip'.
	// Then, we look in that source file for the function.  Then we look
	// for the line number.
	
	// Search the entire set of stabs for the source file (type N_SO).
	lfile = 0;
f0105026:	c7 45 e4 00 00 00 00 	movl   $0x0,-0x1c(%ebp)
	rfile = (stab_end - stabs) - 1;
f010502d:	8b 45 bc             	mov    -0x44(%ebp),%eax
f0105030:	2b 45 c0             	sub    -0x40(%ebp),%eax
f0105033:	c1 f8 02             	sar    $0x2,%eax
f0105036:	69 c0 ab aa aa aa    	imul   $0xaaaaaaab,%eax,%eax
f010503c:	83 e8 01             	sub    $0x1,%eax
f010503f:	89 45 e0             	mov    %eax,-0x20(%ebp)
	stab_binsearch(stabs, &lfile, &rfile, N_SO, addr);
f0105042:	8d 4d e0             	lea    -0x20(%ebp),%ecx
f0105045:	8d 55 e4             	lea    -0x1c(%ebp),%edx
f0105048:	89 74 24 04          	mov    %esi,0x4(%esp)
f010504c:	c7 04 24 64 00 00 00 	movl   $0x64,(%esp)
f0105053:	8b 45 c0             	mov    -0x40(%ebp),%eax
f0105056:	e8 85 fd ff ff       	call   f0104de0 <stab_binsearch>
	if (lfile == 0)
f010505b:	8b 45 e4             	mov    -0x1c(%ebp),%eax
f010505e:	85 c0                	test   %eax,%eax
f0105060:	0f 84 67 01 00 00    	je     f01051cd <debuginfo_eip+0x2bf>
		return -1;

	// Search within that file's stabs for the function definition
	// (N_FUN).
	lfun = lfile;
f0105066:	89 45 dc             	mov    %eax,-0x24(%ebp)
	rfun = rfile;
f0105069:	8b 45 e0             	mov    -0x20(%ebp),%eax
f010506c:	89 45 d8             	mov    %eax,-0x28(%ebp)
	stab_binsearch(stabs, &lfun, &rfun, N_FUN, addr);
f010506f:	8d 4d d8             	lea    -0x28(%ebp),%ecx
f0105072:	8d 55 dc             	lea    -0x24(%ebp),%edx
f0105075:	89 74 24 04          	mov    %esi,0x4(%esp)
f0105079:	c7 04 24 24 00 00 00 	movl   $0x24,(%esp)
f0105080:	8b 45 c0             	mov    -0x40(%ebp),%eax
f0105083:	e8 58 fd ff ff       	call   f0104de0 <stab_binsearch>
	if (lfun <= rfun) {
f0105088:	8b 45 dc             	mov    -0x24(%ebp),%eax
f010508b:	3b 45 d8             	cmp    -0x28(%ebp),%eax
f010508e:	7f 35                	jg     f01050c5 <debuginfo_eip+0x1b7>
		// stabs[lfun] points to the function name
		// in the string table, but check bounds just in case.
		if (stabs[lfun].n_strx < stabstr_end - stabstr)
f0105090:	6b c0 0c             	imul   $0xc,%eax,%eax
f0105093:	8b 55 c0             	mov    -0x40(%ebp),%edx
f0105096:	8b 04 10             	mov    (%eax,%edx,1),%eax
f0105099:	89 fa                	mov    %edi,%edx
f010509b:	2b 55 c4             	sub    -0x3c(%ebp),%edx
f010509e:	39 d0                	cmp    %edx,%eax
f01050a0:	73 06                	jae    f01050a8 <debuginfo_eip+0x19a>
			info->eip_fn_name = stabstr + stabs[lfun].n_strx;
f01050a2:	03 45 c4             	add    -0x3c(%ebp),%eax
f01050a5:	89 43 08             	mov    %eax,0x8(%ebx)
		info->eip_fn_addr = stabs[lfun].n_value;
f01050a8:	8b 55 dc             	mov    -0x24(%ebp),%edx
f01050ab:	6b c2 0c             	imul   $0xc,%edx,%eax
f01050ae:	8b 4d c0             	mov    -0x40(%ebp),%ecx
f01050b1:	8b 44 08 08          	mov    0x8(%eax,%ecx,1),%eax
f01050b5:	89 43 10             	mov    %eax,0x10(%ebx)
		addr -= info->eip_fn_addr;
f01050b8:	29 c6                	sub    %eax,%esi
		lfind	= 1;
		// Search within the function definition for the line number.
		lline = lfun;
f01050ba:	89 55 d4             	mov    %edx,-0x2c(%ebp)
		rline = rfun;
f01050bd:	8b 45 d8             	mov    -0x28(%ebp),%eax
f01050c0:	89 45 d0             	mov    %eax,-0x30(%ebp)
f01050c3:	eb 0f                	jmp    f01050d4 <debuginfo_eip+0x1c6>
	} else {
		// Couldn't find function stab!  Maybe we're in an assembly
		// file.  Search the whole file for the line number.
		info->eip_fn_addr = addr;
f01050c5:	89 73 10             	mov    %esi,0x10(%ebx)
		lline = lfile;
f01050c8:	8b 45 e4             	mov    -0x1c(%ebp),%eax
f01050cb:	89 45 d4             	mov    %eax,-0x2c(%ebp)
		rline = rfile;
f01050ce:	8b 45 e0             	mov    -0x20(%ebp),%eax
f01050d1:	89 45 d0             	mov    %eax,-0x30(%ebp)
	}
	// Ignore stuff after the colon.
	info->eip_fn_namelen = strfind(info->eip_fn_name, ':') - info->eip_fn_name;
f01050d4:	c7 44 24 04 3a 00 00 	movl   $0x3a,0x4(%esp)
f01050db:	00 
f01050dc:	8b 43 08             	mov    0x8(%ebx),%eax
f01050df:	89 04 24             	mov    %eax,(%esp)
f01050e2:	e8 94 09 00 00       	call   f0105a7b <strfind>
f01050e7:	2b 43 08             	sub    0x8(%ebx),%eax
f01050ea:	89 43 0c             	mov    %eax,0xc(%ebx)
	//	There's a particular stabs type used for line numbers.
	//	Look at the STABS documentation and <inc/stab.h> to find
	//	which one.
	// Your code here.

	lfstart	= lline;	
f01050ed:	8b 45 d4             	mov    -0x2c(%ebp),%eax
f01050f0:	89 45 bc             	mov    %eax,-0x44(%ebp)
	stab_binsearch(stabs, &lline, &rline, N_SLINE, addr);
f01050f3:	8d 4d d0             	lea    -0x30(%ebp),%ecx
f01050f6:	8d 55 d4             	lea    -0x2c(%ebp),%edx
f01050f9:	89 74 24 04          	mov    %esi,0x4(%esp)
f01050fd:	c7 04 24 44 00 00 00 	movl   $0x44,(%esp)
f0105104:	8b 45 c0             	mov    -0x40(%ebp),%eax
f0105107:	e8 d4 fc ff ff       	call   f0104de0 <stab_binsearch>

	for (lfind=lline; lfind >=lfstart; lfind--) {
f010510c:	8b 45 d4             	mov    -0x2c(%ebp),%eax
f010510f:	39 45 bc             	cmp    %eax,-0x44(%ebp)
f0105112:	7f 13                	jg     f0105127 <debuginfo_eip+0x219>
		if (stabs [lfind].n_type == N_SLINE)
f0105114:	6b c0 0c             	imul   $0xc,%eax,%eax
f0105117:	03 45 c0             	add    -0x40(%ebp),%eax
f010511a:	80 78 04 44          	cmpb   $0x44,0x4(%eax)
f010511e:	75 07                	jne    f0105127 <debuginfo_eip+0x219>
			info->eip_line	= stabs [lfind].n_desc;
f0105120:	0f b7 40 06          	movzwl 0x6(%eax),%eax
f0105124:	89 43 04             	mov    %eax,0x4(%ebx)
	// stab.
	// We can't just use the "lfile" stab because inlined functions
	// can interpolate code from a different file!
	// Such included source files use the N_SOL stab type.
	while (lline >= lfile
	       && stabs[lline].n_type != N_SOL
f0105127:	8b 45 d4             	mov    -0x2c(%ebp),%eax
f010512a:	8b 55 e4             	mov    -0x1c(%ebp),%edx
f010512d:	89 55 bc             	mov    %edx,-0x44(%ebp)
	// Search backwards from the line number for the relevant filename
	// stab.
	// We can't just use the "lfile" stab because inlined functions
	// can interpolate code from a different file!
	// Such included source files use the N_SOL stab type.
	while (lline >= lfile
f0105130:	39 d0                	cmp    %edx,%eax
f0105132:	7c 58                	jl     f010518c <debuginfo_eip+0x27e>
	       && stabs[lline].n_type != N_SOL
f0105134:	6b f0 0c             	imul   $0xc,%eax,%esi
f0105137:	03 75 c0             	add    -0x40(%ebp),%esi
	       && (stabs[lline].n_type != N_SO || !stabs[lline].n_value))
f010513a:	0f b6 4e 04          	movzbl 0x4(%esi),%ecx
	// Search backwards from the line number for the relevant filename
	// stab.
	// We can't just use the "lfile" stab because inlined functions
	// can interpolate code from a different file!
	// Such included source files use the N_SOL stab type.
	while (lline >= lfile
f010513e:	80 f9 84             	cmp    $0x84,%cl
f0105141:	74 34                	je     f0105177 <debuginfo_eip+0x269>
f0105143:	8d 50 ff             	lea    -0x1(%eax),%edx
f0105146:	6b d2 0c             	imul   $0xc,%edx,%edx
f0105149:	03 55 c0             	add    -0x40(%ebp),%edx
f010514c:	eb 19                	jmp    f0105167 <debuginfo_eip+0x259>
	       && stabs[lline].n_type != N_SOL
	       && (stabs[lline].n_type != N_SO || !stabs[lline].n_value))
		lline--;
f010514e:	83 e8 01             	sub    $0x1,%eax
f0105151:	89 45 d4             	mov    %eax,-0x2c(%ebp)
	// Search backwards from the line number for the relevant filename
	// stab.
	// We can't just use the "lfile" stab because inlined functions
	// can interpolate code from a different file!
	// Such included source files use the N_SOL stab type.
	while (lline >= lfile
f0105154:	39 45 bc             	cmp    %eax,-0x44(%ebp)
f0105157:	7f 33                	jg     f010518c <debuginfo_eip+0x27e>
f0105159:	89 d6                	mov    %edx,%esi
	       && stabs[lline].n_type != N_SOL
	       && (stabs[lline].n_type != N_SO || !stabs[lline].n_value))
f010515b:	0f b6 4a 04          	movzbl 0x4(%edx),%ecx
f010515f:	83 ea 0c             	sub    $0xc,%edx
	// Search backwards from the line number for the relevant filename
	// stab.
	// We can't just use the "lfile" stab because inlined functions
	// can interpolate code from a different file!
	// Such included source files use the N_SOL stab type.
	while (lline >= lfile
f0105162:	80 f9 84             	cmp    $0x84,%cl
f0105165:	74 10                	je     f0105177 <debuginfo_eip+0x269>
f0105167:	80 f9 64             	cmp    $0x64,%cl
f010516a:	75 e2                	jne    f010514e <debuginfo_eip+0x240>
	       && stabs[lline].n_type != N_SOL
	       && (stabs[lline].n_type != N_SO || !stabs[lline].n_value))
f010516c:	83 7e 08 00          	cmpl   $0x0,0x8(%esi)
f0105170:	74 dc                	je     f010514e <debuginfo_eip+0x240>
		lline--;
	if (lline >= lfile && stabs[lline].n_strx < stabstr_end - stabstr)
f0105172:	3b 45 bc             	cmp    -0x44(%ebp),%eax
f0105175:	7c 15                	jl     f010518c <debuginfo_eip+0x27e>
f0105177:	6b c0 0c             	imul   $0xc,%eax,%eax
f010517a:	8b 4d c0             	mov    -0x40(%ebp),%ecx
f010517d:	8b 04 08             	mov    (%eax,%ecx,1),%eax
f0105180:	2b 7d c4             	sub    -0x3c(%ebp),%edi
f0105183:	39 f8                	cmp    %edi,%eax
f0105185:	73 05                	jae    f010518c <debuginfo_eip+0x27e>
		info->eip_file = stabstr + stabs[lline].n_strx;
f0105187:	03 45 c4             	add    -0x3c(%ebp),%eax
f010518a:	89 03                	mov    %eax,(%ebx)


	// Set eip_fn_narg to the number of arguments taken by the function,
	// or 0 if there was no containing function.
	if (lfun < rfun)
f010518c:	8b 45 dc             	mov    -0x24(%ebp),%eax
f010518f:	3b 45 d8             	cmp    -0x28(%ebp),%eax
f0105192:	7d 40                	jge    f01051d4 <debuginfo_eip+0x2c6>
		for (lline = lfun + 1;
f0105194:	83 c0 01             	add    $0x1,%eax
f0105197:	89 45 d4             	mov    %eax,-0x2c(%ebp)
f010519a:	39 45 d8             	cmp    %eax,-0x28(%ebp)
f010519d:	7e 35                	jle    f01051d4 <debuginfo_eip+0x2c6>
		     lline < rfun && stabs[lline].n_type == N_PSYM;
f010519f:	6b c0 0c             	imul   $0xc,%eax,%eax
f01051a2:	8b 55 c0             	mov    -0x40(%ebp),%edx
f01051a5:	80 7c 10 04 a0       	cmpb   $0xa0,0x4(%eax,%edx,1)
f01051aa:	75 28                	jne    f01051d4 <debuginfo_eip+0x2c6>
		     lline++)
			info->eip_fn_narg++;
f01051ac:	83 43 14 01          	addl   $0x1,0x14(%ebx)
	// Set eip_fn_narg to the number of arguments taken by the function,
	// or 0 if there was no containing function.
	if (lfun < rfun)
		for (lline = lfun + 1;
		     lline < rfun && stabs[lline].n_type == N_PSYM;
		     lline++)
f01051b0:	8b 45 d4             	mov    -0x2c(%ebp),%eax
f01051b3:	83 c0 01             	add    $0x1,%eax
f01051b6:	89 45 d4             	mov    %eax,-0x2c(%ebp)


	// Set eip_fn_narg to the number of arguments taken by the function,
	// or 0 if there was no containing function.
	if (lfun < rfun)
		for (lline = lfun + 1;
f01051b9:	39 45 d8             	cmp    %eax,-0x28(%ebp)
f01051bc:	7e 16                	jle    f01051d4 <debuginfo_eip+0x2c6>
		     lline < rfun && stabs[lline].n_type == N_PSYM;
f01051be:	8d 04 40             	lea    (%eax,%eax,2),%eax
f01051c1:	8b 4d c0             	mov    -0x40(%ebp),%ecx
f01051c4:	80 7c 81 04 a0       	cmpb   $0xa0,0x4(%ecx,%eax,4)
f01051c9:	74 e1                	je     f01051ac <debuginfo_eip+0x29e>
f01051cb:	eb 07                	jmp    f01051d4 <debuginfo_eip+0x2c6>
f01051cd:	b8 ff ff ff ff       	mov    $0xffffffff,%eax
f01051d2:	eb 05                	jmp    f01051d9 <debuginfo_eip+0x2cb>
f01051d4:	b8 00 00 00 00       	mov    $0x0,%eax
		     lline++)
			info->eip_fn_narg++;
	
	return 0;
}
f01051d9:	8b 5d f4             	mov    -0xc(%ebp),%ebx
f01051dc:	8b 75 f8             	mov    -0x8(%ebp),%esi
f01051df:	8b 7d fc             	mov    -0x4(%ebp),%edi
f01051e2:	89 ec                	mov    %ebp,%esp
f01051e4:	5d                   	pop    %ebp
f01051e5:	c3                   	ret    
	...

f01051f0 <printnum>:
 * using specified putch function and associated pointer putdat.
 */
static void
printnum(void (*putch)(int, void*), void *putdat,
	 unsigned long long num, unsigned base, int width, int padc)
{
f01051f0:	55                   	push   %ebp
f01051f1:	89 e5                	mov    %esp,%ebp
f01051f3:	57                   	push   %edi
f01051f4:	56                   	push   %esi
f01051f5:	53                   	push   %ebx
f01051f6:	83 ec 4c             	sub    $0x4c,%esp
f01051f9:	89 45 e4             	mov    %eax,-0x1c(%ebp)
f01051fc:	89 d6                	mov    %edx,%esi
f01051fe:	8b 45 08             	mov    0x8(%ebp),%eax
f0105201:	89 45 d8             	mov    %eax,-0x28(%ebp)
f0105204:	8b 55 0c             	mov    0xc(%ebp),%edx
f0105207:	89 55 e0             	mov    %edx,-0x20(%ebp)
f010520a:	8b 45 10             	mov    0x10(%ebp),%eax
f010520d:	8b 5d 14             	mov    0x14(%ebp),%ebx
f0105210:	8b 7d 18             	mov    0x18(%ebp),%edi
	// first recursively print all preceding (more significant) digits
	if (num >= base) {
f0105213:	89 45 dc             	mov    %eax,-0x24(%ebp)
f0105216:	b9 00 00 00 00       	mov    $0x0,%ecx
f010521b:	39 d1                	cmp    %edx,%ecx
f010521d:	72 15                	jb     f0105234 <printnum+0x44>
f010521f:	77 07                	ja     f0105228 <printnum+0x38>
f0105221:	8b 55 d8             	mov    -0x28(%ebp),%edx
f0105224:	39 d0                	cmp    %edx,%eax
f0105226:	76 0c                	jbe    f0105234 <printnum+0x44>
		printnum(putch, putdat, num / base, base, width - 1, padc);
	} else {
		// print any needed pad characters before first digit
		while (--width > 0)
f0105228:	83 eb 01             	sub    $0x1,%ebx
f010522b:	85 db                	test   %ebx,%ebx
f010522d:	8d 76 00             	lea    0x0(%esi),%esi
f0105230:	7f 61                	jg     f0105293 <printnum+0xa3>
f0105232:	eb 70                	jmp    f01052a4 <printnum+0xb4>
printnum(void (*putch)(int, void*), void *putdat,
	 unsigned long long num, unsigned base, int width, int padc)
{
	// first recursively print all preceding (more significant) digits
	if (num >= base) {
		printnum(putch, putdat, num / base, base, width - 1, padc);
f0105234:	89 7c 24 10          	mov    %edi,0x10(%esp)
f0105238:	83 eb 01             	sub    $0x1,%ebx
f010523b:	89 5c 24 0c          	mov    %ebx,0xc(%esp)
f010523f:	89 44 24 08          	mov    %eax,0x8(%esp)
f0105243:	8b 4c 24 08          	mov    0x8(%esp),%ecx
f0105247:	8b 5c 24 0c          	mov    0xc(%esp),%ebx
f010524b:	89 4d d0             	mov    %ecx,-0x30(%ebp)
f010524e:	89 5d d4             	mov    %ebx,-0x2c(%ebp)
f0105251:	8b 5d dc             	mov    -0x24(%ebp),%ebx
f0105254:	89 5c 24 08          	mov    %ebx,0x8(%esp)
f0105258:	c7 44 24 0c 00 00 00 	movl   $0x0,0xc(%esp)
f010525f:	00 
f0105260:	8b 45 d8             	mov    -0x28(%ebp),%eax
f0105263:	89 04 24             	mov    %eax,(%esp)
f0105266:	8b 55 e0             	mov    -0x20(%ebp),%edx
f0105269:	89 54 24 04          	mov    %edx,0x4(%esp)
f010526d:	e8 3e 14 00 00       	call   f01066b0 <__udivdi3>
f0105272:	8b 4d d0             	mov    -0x30(%ebp),%ecx
f0105275:	8b 5d d4             	mov    -0x2c(%ebp),%ebx
f0105278:	89 4c 24 08          	mov    %ecx,0x8(%esp)
f010527c:	89 5c 24 0c          	mov    %ebx,0xc(%esp)
f0105280:	89 04 24             	mov    %eax,(%esp)
f0105283:	89 54 24 04          	mov    %edx,0x4(%esp)
f0105287:	89 f2                	mov    %esi,%edx
f0105289:	8b 45 e4             	mov    -0x1c(%ebp),%eax
f010528c:	e8 5f ff ff ff       	call   f01051f0 <printnum>
f0105291:	eb 11                	jmp    f01052a4 <printnum+0xb4>
	} else {
		// print any needed pad characters before first digit
		while (--width > 0)
			putch(padc, putdat);
f0105293:	89 74 24 04          	mov    %esi,0x4(%esp)
f0105297:	89 3c 24             	mov    %edi,(%esp)
f010529a:	ff 55 e4             	call   *-0x1c(%ebp)
	// first recursively print all preceding (more significant) digits
	if (num >= base) {
		printnum(putch, putdat, num / base, base, width - 1, padc);
	} else {
		// print any needed pad characters before first digit
		while (--width > 0)
f010529d:	83 eb 01             	sub    $0x1,%ebx
f01052a0:	85 db                	test   %ebx,%ebx
f01052a2:	7f ef                	jg     f0105293 <printnum+0xa3>
			putch(padc, putdat);
	}

	// then print this (the least significant) digit
	putch("0123456789abcdef"[num % base], putdat);
f01052a4:	89 74 24 04          	mov    %esi,0x4(%esp)
f01052a8:	8b 74 24 04          	mov    0x4(%esp),%esi
f01052ac:	8b 45 dc             	mov    -0x24(%ebp),%eax
f01052af:	89 44 24 08          	mov    %eax,0x8(%esp)
f01052b3:	c7 44 24 0c 00 00 00 	movl   $0x0,0xc(%esp)
f01052ba:	00 
f01052bb:	8b 55 d8             	mov    -0x28(%ebp),%edx
f01052be:	89 14 24             	mov    %edx,(%esp)
f01052c1:	8b 4d e0             	mov    -0x20(%ebp),%ecx
f01052c4:	89 4c 24 04          	mov    %ecx,0x4(%esp)
f01052c8:	e8 13 15 00 00       	call   f01067e0 <__umoddi3>
f01052cd:	89 74 24 04          	mov    %esi,0x4(%esp)
f01052d1:	0f be 80 5e 7e 10 f0 	movsbl -0xfef81a2(%eax),%eax
f01052d8:	89 04 24             	mov    %eax,(%esp)
f01052db:	ff 55 e4             	call   *-0x1c(%ebp)
}
f01052de:	83 c4 4c             	add    $0x4c,%esp
f01052e1:	5b                   	pop    %ebx
f01052e2:	5e                   	pop    %esi
f01052e3:	5f                   	pop    %edi
f01052e4:	5d                   	pop    %ebp
f01052e5:	c3                   	ret    

f01052e6 <getuint>:

// Get an unsigned int of various possible sizes from a varargs list,
// depending on the lflag parameter.
static unsigned long long
getuint(va_list *ap, int lflag)
{
f01052e6:	55                   	push   %ebp
f01052e7:	89 e5                	mov    %esp,%ebp
	if (lflag >= 2)
f01052e9:	83 fa 01             	cmp    $0x1,%edx
f01052ec:	7e 0e                	jle    f01052fc <getuint+0x16>
		return va_arg(*ap, unsigned long long);
f01052ee:	8b 10                	mov    (%eax),%edx
f01052f0:	8d 4a 08             	lea    0x8(%edx),%ecx
f01052f3:	89 08                	mov    %ecx,(%eax)
f01052f5:	8b 02                	mov    (%edx),%eax
f01052f7:	8b 52 04             	mov    0x4(%edx),%edx
f01052fa:	eb 22                	jmp    f010531e <getuint+0x38>
	else if (lflag)
f01052fc:	85 d2                	test   %edx,%edx
f01052fe:	74 10                	je     f0105310 <getuint+0x2a>
		return va_arg(*ap, unsigned long);
f0105300:	8b 10                	mov    (%eax),%edx
f0105302:	8d 4a 04             	lea    0x4(%edx),%ecx
f0105305:	89 08                	mov    %ecx,(%eax)
f0105307:	8b 02                	mov    (%edx),%eax
f0105309:	ba 00 00 00 00       	mov    $0x0,%edx
f010530e:	eb 0e                	jmp    f010531e <getuint+0x38>
	else
		return va_arg(*ap, unsigned int);
f0105310:	8b 10                	mov    (%eax),%edx
f0105312:	8d 4a 04             	lea    0x4(%edx),%ecx
f0105315:	89 08                	mov    %ecx,(%eax)
f0105317:	8b 02                	mov    (%edx),%eax
f0105319:	ba 00 00 00 00       	mov    $0x0,%edx
}
f010531e:	5d                   	pop    %ebp
f010531f:	c3                   	ret    

f0105320 <sprintputch>:
	int cnt;
};

static void
sprintputch(int ch, struct sprintbuf *b)
{
f0105320:	55                   	push   %ebp
f0105321:	89 e5                	mov    %esp,%ebp
f0105323:	8b 45 0c             	mov    0xc(%ebp),%eax
	b->cnt++;
f0105326:	83 40 08 01          	addl   $0x1,0x8(%eax)
	if (b->buf < b->ebuf)
f010532a:	8b 10                	mov    (%eax),%edx
f010532c:	3b 50 04             	cmp    0x4(%eax),%edx
f010532f:	73 0a                	jae    f010533b <sprintputch+0x1b>
		*b->buf++ = ch;
f0105331:	8b 4d 08             	mov    0x8(%ebp),%ecx
f0105334:	88 0a                	mov    %cl,(%edx)
f0105336:	83 c2 01             	add    $0x1,%edx
f0105339:	89 10                	mov    %edx,(%eax)
}
f010533b:	5d                   	pop    %ebp
f010533c:	c3                   	ret    

f010533d <vprintfmt>:
// Main function to format and print a string.
void printfmt(void (*putch)(int, void*), void *putdat, const char *fmt, ...);

void
vprintfmt(void (*putch)(int, void*), void *putdat, const char *fmt, va_list ap)
{
f010533d:	55                   	push   %ebp
f010533e:	89 e5                	mov    %esp,%ebp
f0105340:	57                   	push   %edi
f0105341:	56                   	push   %esi
f0105342:	53                   	push   %ebx
f0105343:	83 ec 5c             	sub    $0x5c,%esp
f0105346:	8b 7d 08             	mov    0x8(%ebp),%edi
f0105349:	8b 75 0c             	mov    0xc(%ebp),%esi
f010534c:	8b 5d 10             	mov    0x10(%ebp),%ebx
		case '#':
			altflag = 1;
			goto reswitch;

		process_precision:
			if (width < 0)
f010534f:	c7 45 c8 ff ff ff ff 	movl   $0xffffffff,-0x38(%ebp)
f0105356:	eb 11                	jmp    f0105369 <vprintfmt+0x2c>
	int base, lflag, width, precision, altflag;
	char padc;

	while (1) {
		while ((ch = *(unsigned char *) fmt++) != '%') {
			if (ch == '\0')
f0105358:	85 c0                	test   %eax,%eax
f010535a:	0f 84 f9 03 00 00    	je     f0105759 <vprintfmt+0x41c>
				return;
			putch(ch, putdat);
f0105360:	89 74 24 04          	mov    %esi,0x4(%esp)
f0105364:	89 04 24             	mov    %eax,(%esp)
f0105367:	ff d7                	call   *%edi
	unsigned long long num;
	int base, lflag, width, precision, altflag;
	char padc;

	while (1) {
		while ((ch = *(unsigned char *) fmt++) != '%') {
f0105369:	0f b6 03             	movzbl (%ebx),%eax
f010536c:	83 c3 01             	add    $0x1,%ebx
f010536f:	83 f8 25             	cmp    $0x25,%eax
f0105372:	75 e4                	jne    f0105358 <vprintfmt+0x1b>
f0105374:	c6 45 d4 20          	movb   $0x20,-0x2c(%ebp)
f0105378:	c7 45 d8 00 00 00 00 	movl   $0x0,-0x28(%ebp)
f010537f:	c7 45 d0 ff ff ff ff 	movl   $0xffffffff,-0x30(%ebp)
f0105386:	c7 45 e4 ff ff ff ff 	movl   $0xffffffff,-0x1c(%ebp)
f010538d:	b9 00 00 00 00       	mov    $0x0,%ecx
f0105392:	eb 06                	jmp    f010539a <vprintfmt+0x5d>
f0105394:	c6 45 d4 2d          	movb   $0x2d,-0x2c(%ebp)
f0105398:	89 c3                	mov    %eax,%ebx
		width = -1;
		precision = -1;
		lflag = 0;
		altflag = 0;
	reswitch:
		switch (ch = *(unsigned char *) fmt++) {
f010539a:	0f b6 13             	movzbl (%ebx),%edx
f010539d:	0f b6 c2             	movzbl %dl,%eax
f01053a0:	89 45 e0             	mov    %eax,-0x20(%ebp)
f01053a3:	8d 43 01             	lea    0x1(%ebx),%eax
f01053a6:	83 ea 23             	sub    $0x23,%edx
f01053a9:	80 fa 55             	cmp    $0x55,%dl
f01053ac:	0f 87 8a 03 00 00    	ja     f010573c <vprintfmt+0x3ff>
f01053b2:	0f b6 d2             	movzbl %dl,%edx
f01053b5:	ff 24 95 a0 7f 10 f0 	jmp    *-0xfef8060(,%edx,4)
f01053bc:	c6 45 d4 30          	movb   $0x30,-0x2c(%ebp)
f01053c0:	eb d6                	jmp    f0105398 <vprintfmt+0x5b>
		case '6':
		case '7':
		case '8':
		case '9':
			for (precision = 0; ; ++fmt) {
				precision = precision * 10 + ch - '0';
f01053c2:	8b 55 e0             	mov    -0x20(%ebp),%edx
f01053c5:	83 ea 30             	sub    $0x30,%edx
f01053c8:	89 55 d0             	mov    %edx,-0x30(%ebp)
				ch = *fmt;
f01053cb:	0f be 10             	movsbl (%eax),%edx
				if (ch < '0' || ch > '9')
f01053ce:	8d 5a d0             	lea    -0x30(%edx),%ebx
f01053d1:	83 fb 09             	cmp    $0x9,%ebx
f01053d4:	77 54                	ja     f010542a <vprintfmt+0xed>
f01053d6:	89 4d e0             	mov    %ecx,-0x20(%ebp)
f01053d9:	8b 4d d0             	mov    -0x30(%ebp),%ecx
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':
			for (precision = 0; ; ++fmt) {
f01053dc:	83 c0 01             	add    $0x1,%eax
				precision = precision * 10 + ch - '0';
f01053df:	8d 0c 89             	lea    (%ecx,%ecx,4),%ecx
f01053e2:	8d 4c 4a d0          	lea    -0x30(%edx,%ecx,2),%ecx
				ch = *fmt;
f01053e6:	0f be 10             	movsbl (%eax),%edx
				if (ch < '0' || ch > '9')
f01053e9:	8d 5a d0             	lea    -0x30(%edx),%ebx
f01053ec:	83 fb 09             	cmp    $0x9,%ebx
f01053ef:	76 eb                	jbe    f01053dc <vprintfmt+0x9f>
f01053f1:	89 4d d0             	mov    %ecx,-0x30(%ebp)
f01053f4:	8b 4d e0             	mov    -0x20(%ebp),%ecx
f01053f7:	eb 31                	jmp    f010542a <vprintfmt+0xed>
					break;
			}
			goto process_precision;

		case '*':
			precision = va_arg(ap, int);
f01053f9:	8b 55 14             	mov    0x14(%ebp),%edx
f01053fc:	8d 5a 04             	lea    0x4(%edx),%ebx
f01053ff:	89 5d 14             	mov    %ebx,0x14(%ebp)
f0105402:	8b 12                	mov    (%edx),%edx
f0105404:	89 55 d0             	mov    %edx,-0x30(%ebp)
			goto process_precision;
f0105407:	eb 21                	jmp    f010542a <vprintfmt+0xed>

		case '.':
			if (width < 0)
f0105409:	83 7d e4 00          	cmpl   $0x0,-0x1c(%ebp)
f010540d:	ba 00 00 00 00       	mov    $0x0,%edx
f0105412:	0f 49 55 e4          	cmovns -0x1c(%ebp),%edx
f0105416:	89 55 e4             	mov    %edx,-0x1c(%ebp)
f0105419:	e9 7a ff ff ff       	jmp    f0105398 <vprintfmt+0x5b>
f010541e:	c7 45 d8 01 00 00 00 	movl   $0x1,-0x28(%ebp)
				width = 0;
			goto reswitch;

		case '#':
			altflag = 1;
			goto reswitch;
f0105425:	e9 6e ff ff ff       	jmp    f0105398 <vprintfmt+0x5b>

		process_precision:
			if (width < 0)
f010542a:	83 7d e4 00          	cmpl   $0x0,-0x1c(%ebp)
f010542e:	0f 89 64 ff ff ff    	jns    f0105398 <vprintfmt+0x5b>
f0105434:	8b 55 d0             	mov    -0x30(%ebp),%edx
f0105437:	89 55 e4             	mov    %edx,-0x1c(%ebp)
f010543a:	8b 55 c8             	mov    -0x38(%ebp),%edx
f010543d:	89 55 d0             	mov    %edx,-0x30(%ebp)
f0105440:	e9 53 ff ff ff       	jmp    f0105398 <vprintfmt+0x5b>
				width = precision, precision = -1;
			goto reswitch;

		// long flag (doubled for long long)
		case 'l':
			lflag++;
f0105445:	83 c1 01             	add    $0x1,%ecx
			goto reswitch;
f0105448:	e9 4b ff ff ff       	jmp    f0105398 <vprintfmt+0x5b>
f010544d:	89 45 cc             	mov    %eax,-0x34(%ebp)

		// character
		case 'c':
			putch(va_arg(ap, int), putdat);
f0105450:	8b 45 14             	mov    0x14(%ebp),%eax
f0105453:	8d 50 04             	lea    0x4(%eax),%edx
f0105456:	89 55 14             	mov    %edx,0x14(%ebp)
f0105459:	89 74 24 04          	mov    %esi,0x4(%esp)
f010545d:	8b 00                	mov    (%eax),%eax
f010545f:	89 04 24             	mov    %eax,(%esp)
f0105462:	ff d7                	call   *%edi
f0105464:	8b 5d cc             	mov    -0x34(%ebp),%ebx
			break;
f0105467:	e9 fd fe ff ff       	jmp    f0105369 <vprintfmt+0x2c>
f010546c:	89 45 cc             	mov    %eax,-0x34(%ebp)

		// error message
		case 'e':
			err = va_arg(ap, int);
f010546f:	8b 45 14             	mov    0x14(%ebp),%eax
f0105472:	8d 50 04             	lea    0x4(%eax),%edx
f0105475:	89 55 14             	mov    %edx,0x14(%ebp)
f0105478:	8b 00                	mov    (%eax),%eax
f010547a:	89 c2                	mov    %eax,%edx
f010547c:	c1 fa 1f             	sar    $0x1f,%edx
f010547f:	31 d0                	xor    %edx,%eax
f0105481:	29 d0                	sub    %edx,%eax
			if (err < 0)
				err = -err;
			if (err > MAXERROR || (p = error_string[err]) == NULL)
f0105483:	83 f8 12             	cmp    $0x12,%eax
f0105486:	7f 0b                	jg     f0105493 <vprintfmt+0x156>
f0105488:	8b 14 85 00 81 10 f0 	mov    -0xfef7f00(,%eax,4),%edx
f010548f:	85 d2                	test   %edx,%edx
f0105491:	75 20                	jne    f01054b3 <vprintfmt+0x176>
				printfmt(putch, putdat, "error %d", err);
f0105493:	89 44 24 0c          	mov    %eax,0xc(%esp)
f0105497:	c7 44 24 08 6f 7e 10 	movl   $0xf0107e6f,0x8(%esp)
f010549e:	f0 
f010549f:	89 74 24 04          	mov    %esi,0x4(%esp)
f01054a3:	89 3c 24             	mov    %edi,(%esp)
f01054a6:	e8 36 03 00 00       	call   f01057e1 <printfmt>
f01054ab:	8b 5d cc             	mov    -0x34(%ebp),%ebx
		// error message
		case 'e':
			err = va_arg(ap, int);
			if (err < 0)
				err = -err;
			if (err > MAXERROR || (p = error_string[err]) == NULL)
f01054ae:	e9 b6 fe ff ff       	jmp    f0105369 <vprintfmt+0x2c>
				printfmt(putch, putdat, "error %d", err);
			else
				printfmt(putch, putdat, "%s", p);
f01054b3:	89 54 24 0c          	mov    %edx,0xc(%esp)
f01054b7:	c7 44 24 08 9d 6c 10 	movl   $0xf0106c9d,0x8(%esp)
f01054be:	f0 
f01054bf:	89 74 24 04          	mov    %esi,0x4(%esp)
f01054c3:	89 3c 24             	mov    %edi,(%esp)
f01054c6:	e8 16 03 00 00       	call   f01057e1 <printfmt>
f01054cb:	8b 5d cc             	mov    -0x34(%ebp),%ebx
f01054ce:	e9 96 fe ff ff       	jmp    f0105369 <vprintfmt+0x2c>
f01054d3:	89 45 cc             	mov    %eax,-0x34(%ebp)
f01054d6:	89 c3                	mov    %eax,%ebx
f01054d8:	8b 4d d0             	mov    -0x30(%ebp),%ecx
f01054db:	8b 45 e4             	mov    -0x1c(%ebp),%eax
f01054de:	89 45 c4             	mov    %eax,-0x3c(%ebp)
			break;

		// string
		case 's':
			if ((p = va_arg(ap, char *)) == NULL)
f01054e1:	8b 45 14             	mov    0x14(%ebp),%eax
f01054e4:	8d 50 04             	lea    0x4(%eax),%edx
f01054e7:	89 55 14             	mov    %edx,0x14(%ebp)
f01054ea:	8b 00                	mov    (%eax),%eax
f01054ec:	89 45 e0             	mov    %eax,-0x20(%ebp)
f01054ef:	85 c0                	test   %eax,%eax
f01054f1:	b8 78 7e 10 f0       	mov    $0xf0107e78,%eax
f01054f6:	0f 45 45 e0          	cmovne -0x20(%ebp),%eax
f01054fa:	89 45 e0             	mov    %eax,-0x20(%ebp)
				p = "(null)";
			if (width > 0 && padc != '-')
f01054fd:	83 7d c4 00          	cmpl   $0x0,-0x3c(%ebp)
f0105501:	7e 06                	jle    f0105509 <vprintfmt+0x1cc>
f0105503:	80 7d d4 2d          	cmpb   $0x2d,-0x2c(%ebp)
f0105507:	75 13                	jne    f010551c <vprintfmt+0x1df>
				for (width -= strnlen(p, precision); width > 0; width--)
					putch(padc, putdat);
			for (; (ch = *p++) != '\0' && (precision < 0 || --precision >= 0); width--)
f0105509:	8b 55 e0             	mov    -0x20(%ebp),%edx
f010550c:	0f be 02             	movsbl (%edx),%eax
f010550f:	85 c0                	test   %eax,%eax
f0105511:	0f 85 9b 00 00 00    	jne    f01055b2 <vprintfmt+0x275>
f0105517:	e9 88 00 00 00       	jmp    f01055a4 <vprintfmt+0x267>
		// string
		case 's':
			if ((p = va_arg(ap, char *)) == NULL)
				p = "(null)";
			if (width > 0 && padc != '-')
				for (width -= strnlen(p, precision); width > 0; width--)
f010551c:	89 4c 24 04          	mov    %ecx,0x4(%esp)
f0105520:	8b 4d e0             	mov    -0x20(%ebp),%ecx
f0105523:	89 0c 24             	mov    %ecx,(%esp)
f0105526:	e8 f0 03 00 00       	call   f010591b <strnlen>
f010552b:	8b 55 c4             	mov    -0x3c(%ebp),%edx
f010552e:	29 c2                	sub    %eax,%edx
f0105530:	89 55 e4             	mov    %edx,-0x1c(%ebp)
f0105533:	85 d2                	test   %edx,%edx
f0105535:	7e d2                	jle    f0105509 <vprintfmt+0x1cc>
					putch(padc, putdat);
f0105537:	0f be 4d d4          	movsbl -0x2c(%ebp),%ecx
f010553b:	89 4d d4             	mov    %ecx,-0x2c(%ebp)
f010553e:	89 5d c4             	mov    %ebx,-0x3c(%ebp)
f0105541:	89 d3                	mov    %edx,%ebx
f0105543:	89 74 24 04          	mov    %esi,0x4(%esp)
f0105547:	8b 45 d4             	mov    -0x2c(%ebp),%eax
f010554a:	89 04 24             	mov    %eax,(%esp)
f010554d:	ff d7                	call   *%edi
		// string
		case 's':
			if ((p = va_arg(ap, char *)) == NULL)
				p = "(null)";
			if (width > 0 && padc != '-')
				for (width -= strnlen(p, precision); width > 0; width--)
f010554f:	83 eb 01             	sub    $0x1,%ebx
f0105552:	85 db                	test   %ebx,%ebx
f0105554:	7f ed                	jg     f0105543 <vprintfmt+0x206>
f0105556:	8b 5d c4             	mov    -0x3c(%ebp),%ebx
f0105559:	c7 45 e4 00 00 00 00 	movl   $0x0,-0x1c(%ebp)
f0105560:	eb a7                	jmp    f0105509 <vprintfmt+0x1cc>
					putch(padc, putdat);
			for (; (ch = *p++) != '\0' && (precision < 0 || --precision >= 0); width--)
				if (altflag && (ch < ' ' || ch > '~'))
f0105562:	83 7d d8 00          	cmpl   $0x0,-0x28(%ebp)
f0105566:	74 1a                	je     f0105582 <vprintfmt+0x245>
f0105568:	8d 50 e0             	lea    -0x20(%eax),%edx
f010556b:	83 fa 5e             	cmp    $0x5e,%edx
f010556e:	76 12                	jbe    f0105582 <vprintfmt+0x245>
					putch('?', putdat);
f0105570:	89 7c 24 04          	mov    %edi,0x4(%esp)
f0105574:	c7 04 24 3f 00 00 00 	movl   $0x3f,(%esp)
f010557b:	ff 55 e0             	call   *-0x20(%ebp)
				p = "(null)";
			if (width > 0 && padc != '-')
				for (width -= strnlen(p, precision); width > 0; width--)
					putch(padc, putdat);
			for (; (ch = *p++) != '\0' && (precision < 0 || --precision >= 0); width--)
				if (altflag && (ch < ' ' || ch > '~'))
f010557e:	66 90                	xchg   %ax,%ax
f0105580:	eb 0a                	jmp    f010558c <vprintfmt+0x24f>
					putch('?', putdat);
				else
					putch(ch, putdat);
f0105582:	89 7c 24 04          	mov    %edi,0x4(%esp)
f0105586:	89 04 24             	mov    %eax,(%esp)
f0105589:	ff 55 e0             	call   *-0x20(%ebp)
			if ((p = va_arg(ap, char *)) == NULL)
				p = "(null)";
			if (width > 0 && padc != '-')
				for (width -= strnlen(p, precision); width > 0; width--)
					putch(padc, putdat);
			for (; (ch = *p++) != '\0' && (precision < 0 || --precision >= 0); width--)
f010558c:	83 6d e4 01          	subl   $0x1,-0x1c(%ebp)
f0105590:	0f be 03             	movsbl (%ebx),%eax
f0105593:	85 c0                	test   %eax,%eax
f0105595:	74 05                	je     f010559c <vprintfmt+0x25f>
f0105597:	83 c3 01             	add    $0x1,%ebx
f010559a:	eb 29                	jmp    f01055c5 <vprintfmt+0x288>
f010559c:	89 fe                	mov    %edi,%esi
f010559e:	8b 7d e0             	mov    -0x20(%ebp),%edi
f01055a1:	8b 5d d0             	mov    -0x30(%ebp),%ebx
				if (altflag && (ch < ' ' || ch > '~'))
					putch('?', putdat);
				else
					putch(ch, putdat);
			for (; width > 0; width--)
f01055a4:	83 7d e4 00          	cmpl   $0x0,-0x1c(%ebp)
f01055a8:	7f 2e                	jg     f01055d8 <vprintfmt+0x29b>
f01055aa:	8b 5d cc             	mov    -0x34(%ebp),%ebx
f01055ad:	e9 b7 fd ff ff       	jmp    f0105369 <vprintfmt+0x2c>
			if ((p = va_arg(ap, char *)) == NULL)
				p = "(null)";
			if (width > 0 && padc != '-')
				for (width -= strnlen(p, precision); width > 0; width--)
					putch(padc, putdat);
			for (; (ch = *p++) != '\0' && (precision < 0 || --precision >= 0); width--)
f01055b2:	8b 55 e0             	mov    -0x20(%ebp),%edx
f01055b5:	83 c2 01             	add    $0x1,%edx
f01055b8:	89 7d e0             	mov    %edi,-0x20(%ebp)
f01055bb:	89 f7                	mov    %esi,%edi
f01055bd:	8b 75 d0             	mov    -0x30(%ebp),%esi
f01055c0:	89 5d d0             	mov    %ebx,-0x30(%ebp)
f01055c3:	89 d3                	mov    %edx,%ebx
f01055c5:	85 f6                	test   %esi,%esi
f01055c7:	78 99                	js     f0105562 <vprintfmt+0x225>
f01055c9:	83 ee 01             	sub    $0x1,%esi
f01055cc:	79 94                	jns    f0105562 <vprintfmt+0x225>
f01055ce:	89 fe                	mov    %edi,%esi
f01055d0:	8b 7d e0             	mov    -0x20(%ebp),%edi
f01055d3:	8b 5d d0             	mov    -0x30(%ebp),%ebx
f01055d6:	eb cc                	jmp    f01055a4 <vprintfmt+0x267>
f01055d8:	89 5d d8             	mov    %ebx,-0x28(%ebp)
f01055db:	8b 5d e4             	mov    -0x1c(%ebp),%ebx
				if (altflag && (ch < ' ' || ch > '~'))
					putch('?', putdat);
				else
					putch(ch, putdat);
			for (; width > 0; width--)
				putch(' ', putdat);
f01055de:	89 74 24 04          	mov    %esi,0x4(%esp)
f01055e2:	c7 04 24 20 00 00 00 	movl   $0x20,(%esp)
f01055e9:	ff d7                	call   *%edi
			for (; (ch = *p++) != '\0' && (precision < 0 || --precision >= 0); width--)
				if (altflag && (ch < ' ' || ch > '~'))
					putch('?', putdat);
				else
					putch(ch, putdat);
			for (; width > 0; width--)
f01055eb:	83 eb 01             	sub    $0x1,%ebx
f01055ee:	85 db                	test   %ebx,%ebx
f01055f0:	7f ec                	jg     f01055de <vprintfmt+0x2a1>
f01055f2:	8b 5d d8             	mov    -0x28(%ebp),%ebx
f01055f5:	e9 6f fd ff ff       	jmp    f0105369 <vprintfmt+0x2c>
f01055fa:	89 45 cc             	mov    %eax,-0x34(%ebp)
// Same as getuint but signed - can't use getuint
// because of sign extension
static long long
getint(va_list *ap, int lflag)
{
	if (lflag >= 2)
f01055fd:	83 f9 01             	cmp    $0x1,%ecx
f0105600:	7e 16                	jle    f0105618 <vprintfmt+0x2db>
		return va_arg(*ap, long long);
f0105602:	8b 45 14             	mov    0x14(%ebp),%eax
f0105605:	8d 50 08             	lea    0x8(%eax),%edx
f0105608:	89 55 14             	mov    %edx,0x14(%ebp)
f010560b:	8b 10                	mov    (%eax),%edx
f010560d:	8b 48 04             	mov    0x4(%eax),%ecx
f0105610:	89 55 d8             	mov    %edx,-0x28(%ebp)
f0105613:	89 4d dc             	mov    %ecx,-0x24(%ebp)
f0105616:	eb 32                	jmp    f010564a <vprintfmt+0x30d>
	else if (lflag)
f0105618:	85 c9                	test   %ecx,%ecx
f010561a:	74 18                	je     f0105634 <vprintfmt+0x2f7>
		return va_arg(*ap, long);
f010561c:	8b 45 14             	mov    0x14(%ebp),%eax
f010561f:	8d 50 04             	lea    0x4(%eax),%edx
f0105622:	89 55 14             	mov    %edx,0x14(%ebp)
f0105625:	8b 00                	mov    (%eax),%eax
f0105627:	89 45 d8             	mov    %eax,-0x28(%ebp)
f010562a:	89 c1                	mov    %eax,%ecx
f010562c:	c1 f9 1f             	sar    $0x1f,%ecx
f010562f:	89 4d dc             	mov    %ecx,-0x24(%ebp)
f0105632:	eb 16                	jmp    f010564a <vprintfmt+0x30d>
	else
		return va_arg(*ap, int);
f0105634:	8b 45 14             	mov    0x14(%ebp),%eax
f0105637:	8d 50 04             	lea    0x4(%eax),%edx
f010563a:	89 55 14             	mov    %edx,0x14(%ebp)
f010563d:	8b 00                	mov    (%eax),%eax
f010563f:	89 45 d8             	mov    %eax,-0x28(%ebp)
f0105642:	89 c2                	mov    %eax,%edx
f0105644:	c1 fa 1f             	sar    $0x1f,%edx
f0105647:	89 55 dc             	mov    %edx,-0x24(%ebp)
				putch(' ', putdat);
			break;

		// (signed) decimal
		case 'd':
			num = getint(&ap, lflag);
f010564a:	8b 4d d8             	mov    -0x28(%ebp),%ecx
f010564d:	8b 5d dc             	mov    -0x24(%ebp),%ebx
f0105650:	b8 0a 00 00 00       	mov    $0xa,%eax
			if ((long long) num < 0) {
f0105655:	83 7d dc 00          	cmpl   $0x0,-0x24(%ebp)
f0105659:	0f 89 9b 00 00 00    	jns    f01056fa <vprintfmt+0x3bd>
				putch('-', putdat);
f010565f:	89 74 24 04          	mov    %esi,0x4(%esp)
f0105663:	c7 04 24 2d 00 00 00 	movl   $0x2d,(%esp)
f010566a:	ff d7                	call   *%edi
				num = -(long long) num;
f010566c:	8b 4d d8             	mov    -0x28(%ebp),%ecx
f010566f:	8b 5d dc             	mov    -0x24(%ebp),%ebx
f0105672:	f7 d9                	neg    %ecx
f0105674:	83 d3 00             	adc    $0x0,%ebx
f0105677:	f7 db                	neg    %ebx
f0105679:	b8 0a 00 00 00       	mov    $0xa,%eax
f010567e:	eb 7a                	jmp    f01056fa <vprintfmt+0x3bd>
f0105680:	89 45 cc             	mov    %eax,-0x34(%ebp)
			base = 10;
			goto number;

		// unsigned decimal
		case 'u':
			num = getuint(&ap, lflag);
f0105683:	89 ca                	mov    %ecx,%edx
f0105685:	8d 45 14             	lea    0x14(%ebp),%eax
f0105688:	e8 59 fc ff ff       	call   f01052e6 <getuint>
f010568d:	89 c1                	mov    %eax,%ecx
f010568f:	89 d3                	mov    %edx,%ebx
f0105691:	b8 0a 00 00 00       	mov    $0xa,%eax
			base = 10;
			goto number;
f0105696:	eb 62                	jmp    f01056fa <vprintfmt+0x3bd>
f0105698:	89 45 cc             	mov    %eax,-0x34(%ebp)

		// (unsigned) octal
		case 'o':
			num = getuint(&ap, lflag);
f010569b:	89 ca                	mov    %ecx,%edx
f010569d:	8d 45 14             	lea    0x14(%ebp),%eax
f01056a0:	e8 41 fc ff ff       	call   f01052e6 <getuint>
f01056a5:	89 c1                	mov    %eax,%ecx
f01056a7:	89 d3                	mov    %edx,%ebx
f01056a9:	b8 08 00 00 00       	mov    $0x8,%eax
			base = 8;
			goto number;
f01056ae:	eb 4a                	jmp    f01056fa <vprintfmt+0x3bd>
f01056b0:	89 45 cc             	mov    %eax,-0x34(%ebp)
			break;
			**/

		// pointer
		case 'p':
			putch('0', putdat);
f01056b3:	89 74 24 04          	mov    %esi,0x4(%esp)
f01056b7:	c7 04 24 30 00 00 00 	movl   $0x30,(%esp)
f01056be:	ff d7                	call   *%edi
			putch('x', putdat);
f01056c0:	89 74 24 04          	mov    %esi,0x4(%esp)
f01056c4:	c7 04 24 78 00 00 00 	movl   $0x78,(%esp)
f01056cb:	ff d7                	call   *%edi
			num = (unsigned long long)
f01056cd:	8b 45 14             	mov    0x14(%ebp),%eax
f01056d0:	8d 50 04             	lea    0x4(%eax),%edx
f01056d3:	89 55 14             	mov    %edx,0x14(%ebp)
f01056d6:	8b 08                	mov    (%eax),%ecx
f01056d8:	bb 00 00 00 00       	mov    $0x0,%ebx
f01056dd:	b8 10 00 00 00       	mov    $0x10,%eax
				(uintptr_t) va_arg(ap, void *);
			base = 16;
			goto number;
f01056e2:	eb 16                	jmp    f01056fa <vprintfmt+0x3bd>
f01056e4:	89 45 cc             	mov    %eax,-0x34(%ebp)

		// (unsigned) hexadecimal
		case 'x':
			num = getuint(&ap, lflag);
f01056e7:	89 ca                	mov    %ecx,%edx
f01056e9:	8d 45 14             	lea    0x14(%ebp),%eax
f01056ec:	e8 f5 fb ff ff       	call   f01052e6 <getuint>
f01056f1:	89 c1                	mov    %eax,%ecx
f01056f3:	89 d3                	mov    %edx,%ebx
f01056f5:	b8 10 00 00 00       	mov    $0x10,%eax
			base = 16;
		number:
			printnum(putch, putdat, num, base, width, padc);
f01056fa:	0f be 55 d4          	movsbl -0x2c(%ebp),%edx
f01056fe:	89 54 24 10          	mov    %edx,0x10(%esp)
f0105702:	8b 55 e4             	mov    -0x1c(%ebp),%edx
f0105705:	89 54 24 0c          	mov    %edx,0xc(%esp)
f0105709:	89 44 24 08          	mov    %eax,0x8(%esp)
f010570d:	89 0c 24             	mov    %ecx,(%esp)
f0105710:	89 5c 24 04          	mov    %ebx,0x4(%esp)
f0105714:	89 f2                	mov    %esi,%edx
f0105716:	89 f8                	mov    %edi,%eax
f0105718:	e8 d3 fa ff ff       	call   f01051f0 <printnum>
f010571d:	8b 5d cc             	mov    -0x34(%ebp),%ebx
			break;
f0105720:	e9 44 fc ff ff       	jmp    f0105369 <vprintfmt+0x2c>
f0105725:	89 45 cc             	mov    %eax,-0x34(%ebp)
f0105728:	8b 55 e0             	mov    -0x20(%ebp),%edx

		// escaped '%' character
		case '%':
			putch(ch, putdat);
f010572b:	89 74 24 04          	mov    %esi,0x4(%esp)
f010572f:	89 14 24             	mov    %edx,(%esp)
f0105732:	ff d7                	call   *%edi
f0105734:	8b 5d cc             	mov    -0x34(%ebp),%ebx
			break;
f0105737:	e9 2d fc ff ff       	jmp    f0105369 <vprintfmt+0x2c>
			
		// unrecognized escape sequence - just print it literally
		default:
			putch('%', putdat);
f010573c:	89 74 24 04          	mov    %esi,0x4(%esp)
f0105740:	c7 04 24 25 00 00 00 	movl   $0x25,(%esp)
f0105747:	ff d7                	call   *%edi
			for (fmt--; fmt[-1] != '%'; fmt--)
f0105749:	8d 43 ff             	lea    -0x1(%ebx),%eax
f010574c:	80 38 25             	cmpb   $0x25,(%eax)
f010574f:	0f 84 14 fc ff ff    	je     f0105369 <vprintfmt+0x2c>
f0105755:	89 c3                	mov    %eax,%ebx
f0105757:	eb f0                	jmp    f0105749 <vprintfmt+0x40c>
				/* do nothing */;
			break;
		}
	}
}
f0105759:	83 c4 5c             	add    $0x5c,%esp
f010575c:	5b                   	pop    %ebx
f010575d:	5e                   	pop    %esi
f010575e:	5f                   	pop    %edi
f010575f:	5d                   	pop    %ebp
f0105760:	c3                   	ret    

f0105761 <vsnprintf>:
		*b->buf++ = ch;
}

int
vsnprintf(char *buf, int n, const char *fmt, va_list ap)
{
f0105761:	55                   	push   %ebp
f0105762:	89 e5                	mov    %esp,%ebp
f0105764:	83 ec 28             	sub    $0x28,%esp
f0105767:	8b 45 08             	mov    0x8(%ebp),%eax
f010576a:	8b 55 0c             	mov    0xc(%ebp),%edx
	struct sprintbuf b = {buf, buf+n-1, 0};

	if (buf == NULL || n < 1)
f010576d:	85 c0                	test   %eax,%eax
f010576f:	74 04                	je     f0105775 <vsnprintf+0x14>
f0105771:	85 d2                	test   %edx,%edx
f0105773:	7f 07                	jg     f010577c <vsnprintf+0x1b>
f0105775:	b8 fd ff ff ff       	mov    $0xfffffffd,%eax
f010577a:	eb 3b                	jmp    f01057b7 <vsnprintf+0x56>
}

int
vsnprintf(char *buf, int n, const char *fmt, va_list ap)
{
	struct sprintbuf b = {buf, buf+n-1, 0};
f010577c:	89 45 ec             	mov    %eax,-0x14(%ebp)
f010577f:	8d 44 10 ff          	lea    -0x1(%eax,%edx,1),%eax
f0105783:	89 45 f0             	mov    %eax,-0x10(%ebp)
f0105786:	c7 45 f4 00 00 00 00 	movl   $0x0,-0xc(%ebp)

	if (buf == NULL || n < 1)
		return -E_INVAL;

	// print the string to the buffer
	vprintfmt((void*)sprintputch, &b, fmt, ap);
f010578d:	8b 45 14             	mov    0x14(%ebp),%eax
f0105790:	89 44 24 0c          	mov    %eax,0xc(%esp)
f0105794:	8b 45 10             	mov    0x10(%ebp),%eax
f0105797:	89 44 24 08          	mov    %eax,0x8(%esp)
f010579b:	8d 45 ec             	lea    -0x14(%ebp),%eax
f010579e:	89 44 24 04          	mov    %eax,0x4(%esp)
f01057a2:	c7 04 24 20 53 10 f0 	movl   $0xf0105320,(%esp)
f01057a9:	e8 8f fb ff ff       	call   f010533d <vprintfmt>

	// null terminate the buffer
	*b.buf = '\0';
f01057ae:	8b 45 ec             	mov    -0x14(%ebp),%eax
f01057b1:	c6 00 00             	movb   $0x0,(%eax)

	return b.cnt;
f01057b4:	8b 45 f4             	mov    -0xc(%ebp),%eax
}
f01057b7:	c9                   	leave  
f01057b8:	c3                   	ret    

f01057b9 <snprintf>:

int
snprintf(char *buf, int n, const char *fmt, ...)
{
f01057b9:	55                   	push   %ebp
f01057ba:	89 e5                	mov    %esp,%ebp
f01057bc:	83 ec 18             	sub    $0x18,%esp

	return b.cnt;
}

int
snprintf(char *buf, int n, const char *fmt, ...)
f01057bf:	8d 45 14             	lea    0x14(%ebp),%eax
{
	va_list ap;
	int rc;

	va_start(ap, fmt);
	rc = vsnprintf(buf, n, fmt, ap);
f01057c2:	89 44 24 0c          	mov    %eax,0xc(%esp)
f01057c6:	8b 45 10             	mov    0x10(%ebp),%eax
f01057c9:	89 44 24 08          	mov    %eax,0x8(%esp)
f01057cd:	8b 45 0c             	mov    0xc(%ebp),%eax
f01057d0:	89 44 24 04          	mov    %eax,0x4(%esp)
f01057d4:	8b 45 08             	mov    0x8(%ebp),%eax
f01057d7:	89 04 24             	mov    %eax,(%esp)
f01057da:	e8 82 ff ff ff       	call   f0105761 <vsnprintf>
	va_end(ap);

	return rc;
}
f01057df:	c9                   	leave  
f01057e0:	c3                   	ret    

f01057e1 <printfmt>:
	}
}

void
printfmt(void (*putch)(int, void*), void *putdat, const char *fmt, ...)
{
f01057e1:	55                   	push   %ebp
f01057e2:	89 e5                	mov    %esp,%ebp
f01057e4:	83 ec 18             	sub    $0x18,%esp
		}
	}
}

void
printfmt(void (*putch)(int, void*), void *putdat, const char *fmt, ...)
f01057e7:	8d 45 14             	lea    0x14(%ebp),%eax
{
	va_list ap;

	va_start(ap, fmt);
	vprintfmt(putch, putdat, fmt, ap);
f01057ea:	89 44 24 0c          	mov    %eax,0xc(%esp)
f01057ee:	8b 45 10             	mov    0x10(%ebp),%eax
f01057f1:	89 44 24 08          	mov    %eax,0x8(%esp)
f01057f5:	8b 45 0c             	mov    0xc(%ebp),%eax
f01057f8:	89 44 24 04          	mov    %eax,0x4(%esp)
f01057fc:	8b 45 08             	mov    0x8(%ebp),%eax
f01057ff:	89 04 24             	mov    %eax,(%esp)
f0105802:	e8 36 fb ff ff       	call   f010533d <vprintfmt>
	va_end(ap);
}
f0105807:	c9                   	leave  
f0105808:	c3                   	ret    
f0105809:	00 00                	add    %al,(%eax)
f010580b:	00 00                	add    %al,(%eax)
f010580d:	00 00                	add    %al,(%eax)
	...

f0105810 <readline>:
#define BUFLEN 1024
static char buf[BUFLEN];

char *
readline(const char *prompt)
{
f0105810:	55                   	push   %ebp
f0105811:	89 e5                	mov    %esp,%ebp
f0105813:	57                   	push   %edi
f0105814:	56                   	push   %esi
f0105815:	53                   	push   %ebx
f0105816:	83 ec 1c             	sub    $0x1c,%esp
f0105819:	8b 45 08             	mov    0x8(%ebp),%eax
	int i, c, echoing;

#if JOS_KERNEL
	if (prompt != NULL)
f010581c:	85 c0                	test   %eax,%eax
f010581e:	74 10                	je     f0105830 <readline+0x20>
		cprintf("%s", prompt);
f0105820:	89 44 24 04          	mov    %eax,0x4(%esp)
f0105824:	c7 04 24 9d 6c 10 f0 	movl   $0xf0106c9d,(%esp)
f010582b:	e8 af e1 ff ff       	call   f01039df <cprintf>
	if (prompt != NULL)
		fprintf(1, "%s", prompt);
#endif

	i = 0;
	echoing = iscons(0);
f0105830:	c7 04 24 00 00 00 00 	movl   $0x0,(%esp)
f0105837:	e8 54 aa ff ff       	call   f0100290 <iscons>
f010583c:	89 c7                	mov    %eax,%edi
f010583e:	be 00 00 00 00       	mov    $0x0,%esi
	while (1) {
		c = getchar();
f0105843:	e8 37 aa ff ff       	call   f010027f <getchar>
f0105848:	89 c3                	mov    %eax,%ebx
		if (c < 0) {
f010584a:	85 c0                	test   %eax,%eax
f010584c:	79 25                	jns    f0105873 <readline+0x63>
			if (c != -E_EOF)
f010584e:	b8 00 00 00 00       	mov    $0x0,%eax
f0105853:	83 fb f8             	cmp    $0xfffffff8,%ebx
f0105856:	0f 84 96 00 00 00    	je     f01058f2 <readline+0xe2>
				cprintf("read error: %e\n", c);
f010585c:	89 5c 24 04          	mov    %ebx,0x4(%esp)
f0105860:	c7 04 24 6b 81 10 f0 	movl   $0xf010816b,(%esp)
f0105867:	e8 73 e1 ff ff       	call   f01039df <cprintf>
f010586c:	b8 00 00 00 00       	mov    $0x0,%eax
f0105871:	eb 7f                	jmp    f01058f2 <readline+0xe2>
			return NULL;
		} else if ((c == '\b' || c == '\x7f') && i > 0) {
f0105873:	83 f8 08             	cmp    $0x8,%eax
f0105876:	74 0a                	je     f0105882 <readline+0x72>
f0105878:	83 f8 7f             	cmp    $0x7f,%eax
f010587b:	90                   	nop
f010587c:	8d 74 26 00          	lea    0x0(%esi,%eiz,1),%esi
f0105880:	75 19                	jne    f010589b <readline+0x8b>
f0105882:	85 f6                	test   %esi,%esi
f0105884:	7e 15                	jle    f010589b <readline+0x8b>
			if (echoing)
f0105886:	85 ff                	test   %edi,%edi
f0105888:	74 0c                	je     f0105896 <readline+0x86>
				cputchar('\b');
f010588a:	c7 04 24 08 00 00 00 	movl   $0x8,(%esp)
f0105891:	e8 18 ae ff ff       	call   f01006ae <cputchar>
			i--;
f0105896:	83 ee 01             	sub    $0x1,%esi
		c = getchar();
		if (c < 0) {
			if (c != -E_EOF)
				cprintf("read error: %e\n", c);
			return NULL;
		} else if ((c == '\b' || c == '\x7f') && i > 0) {
f0105899:	eb a8                	jmp    f0105843 <readline+0x33>
			if (echoing)
				cputchar('\b');
			i--;
		} else if (c >= ' ' && i < BUFLEN-1) {
f010589b:	83 fb 1f             	cmp    $0x1f,%ebx
f010589e:	66 90                	xchg   %ax,%ax
f01058a0:	7e 26                	jle    f01058c8 <readline+0xb8>
f01058a2:	81 fe fe 03 00 00    	cmp    $0x3fe,%esi
f01058a8:	7f 1e                	jg     f01058c8 <readline+0xb8>
			if (echoing)
f01058aa:	85 ff                	test   %edi,%edi
f01058ac:	8d 74 26 00          	lea    0x0(%esi,%eiz,1),%esi
f01058b0:	74 08                	je     f01058ba <readline+0xaa>
				cputchar(c);
f01058b2:	89 1c 24             	mov    %ebx,(%esp)
f01058b5:	e8 f4 ad ff ff       	call   f01006ae <cputchar>
			buf[i++] = c;
f01058ba:	88 9e 00 fb 2c f0    	mov    %bl,-0xfd30500(%esi)
f01058c0:	83 c6 01             	add    $0x1,%esi
f01058c3:	e9 7b ff ff ff       	jmp    f0105843 <readline+0x33>
		} else if (c == '\n' || c == '\r') {
f01058c8:	83 fb 0a             	cmp    $0xa,%ebx
f01058cb:	74 09                	je     f01058d6 <readline+0xc6>
f01058cd:	83 fb 0d             	cmp    $0xd,%ebx
f01058d0:	0f 85 6d ff ff ff    	jne    f0105843 <readline+0x33>
			if (echoing)
f01058d6:	85 ff                	test   %edi,%edi
f01058d8:	74 0c                	je     f01058e6 <readline+0xd6>
				cputchar('\n');
f01058da:	c7 04 24 0a 00 00 00 	movl   $0xa,(%esp)
f01058e1:	e8 c8 ad ff ff       	call   f01006ae <cputchar>
			buf[i] = 0;
f01058e6:	c6 86 00 fb 2c f0 00 	movb   $0x0,-0xfd30500(%esi)
f01058ed:	b8 00 fb 2c f0       	mov    $0xf02cfb00,%eax
			return buf;
		}
	}
}
f01058f2:	83 c4 1c             	add    $0x1c,%esp
f01058f5:	5b                   	pop    %ebx
f01058f6:	5e                   	pop    %esi
f01058f7:	5f                   	pop    %edi
f01058f8:	5d                   	pop    %ebp
f01058f9:	c3                   	ret    
f01058fa:	00 00                	add    %al,(%eax)
f01058fc:	00 00                	add    %al,(%eax)
	...

f0105900 <strlen>:
// Primespipe runs 3x faster this way.
#define ASM 1

int
strlen(const char *s)
{
f0105900:	55                   	push   %ebp
f0105901:	89 e5                	mov    %esp,%ebp
f0105903:	8b 55 08             	mov    0x8(%ebp),%edx
	int n;

	for (n = 0; *s != '\0'; s++)
f0105906:	b8 00 00 00 00       	mov    $0x0,%eax
f010590b:	80 3a 00             	cmpb   $0x0,(%edx)
f010590e:	74 09                	je     f0105919 <strlen+0x19>
		n++;
f0105910:	83 c0 01             	add    $0x1,%eax
int
strlen(const char *s)
{
	int n;

	for (n = 0; *s != '\0'; s++)
f0105913:	80 3c 02 00          	cmpb   $0x0,(%edx,%eax,1)
f0105917:	75 f7                	jne    f0105910 <strlen+0x10>
		n++;
	return n;
}
f0105919:	5d                   	pop    %ebp
f010591a:	c3                   	ret    

f010591b <strnlen>:

int
strnlen(const char *s, size_t size)
{
f010591b:	55                   	push   %ebp
f010591c:	89 e5                	mov    %esp,%ebp
f010591e:	53                   	push   %ebx
f010591f:	8b 5d 08             	mov    0x8(%ebp),%ebx
f0105922:	8b 4d 0c             	mov    0xc(%ebp),%ecx
	int n;

	for (n = 0; size > 0 && *s != '\0'; s++, size--)
f0105925:	85 c9                	test   %ecx,%ecx
f0105927:	74 19                	je     f0105942 <strnlen+0x27>
f0105929:	80 3b 00             	cmpb   $0x0,(%ebx)
f010592c:	74 14                	je     f0105942 <strnlen+0x27>
f010592e:	b8 00 00 00 00       	mov    $0x0,%eax
		n++;
f0105933:	83 c0 01             	add    $0x1,%eax
int
strnlen(const char *s, size_t size)
{
	int n;

	for (n = 0; size > 0 && *s != '\0'; s++, size--)
f0105936:	39 c8                	cmp    %ecx,%eax
f0105938:	74 0d                	je     f0105947 <strnlen+0x2c>
f010593a:	80 3c 03 00          	cmpb   $0x0,(%ebx,%eax,1)
f010593e:	75 f3                	jne    f0105933 <strnlen+0x18>
f0105940:	eb 05                	jmp    f0105947 <strnlen+0x2c>
f0105942:	b8 00 00 00 00       	mov    $0x0,%eax
		n++;
	return n;
}
f0105947:	5b                   	pop    %ebx
f0105948:	5d                   	pop    %ebp
f0105949:	c3                   	ret    

f010594a <strcpy>:

char *
strcpy(char *dst, const char *src)
{
f010594a:	55                   	push   %ebp
f010594b:	89 e5                	mov    %esp,%ebp
f010594d:	53                   	push   %ebx
f010594e:	8b 45 08             	mov    0x8(%ebp),%eax
f0105951:	8b 5d 0c             	mov    0xc(%ebp),%ebx
f0105954:	ba 00 00 00 00       	mov    $0x0,%edx
	char *ret;

	ret = dst;
	while ((*dst++ = *src++) != '\0')
f0105959:	0f b6 0c 13          	movzbl (%ebx,%edx,1),%ecx
f010595d:	88 0c 10             	mov    %cl,(%eax,%edx,1)
f0105960:	83 c2 01             	add    $0x1,%edx
f0105963:	84 c9                	test   %cl,%cl
f0105965:	75 f2                	jne    f0105959 <strcpy+0xf>
		/* do nothing */;
	return ret;
}
f0105967:	5b                   	pop    %ebx
f0105968:	5d                   	pop    %ebp
f0105969:	c3                   	ret    

f010596a <strncpy>:

char *
strncpy(char *dst, const char *src, size_t size) {
f010596a:	55                   	push   %ebp
f010596b:	89 e5                	mov    %esp,%ebp
f010596d:	56                   	push   %esi
f010596e:	53                   	push   %ebx
f010596f:	8b 45 08             	mov    0x8(%ebp),%eax
f0105972:	8b 55 0c             	mov    0xc(%ebp),%edx
f0105975:	8b 75 10             	mov    0x10(%ebp),%esi
	size_t i;
	char *ret;

	ret = dst;
	for (i = 0; i < size; i++) {
f0105978:	85 f6                	test   %esi,%esi
f010597a:	74 18                	je     f0105994 <strncpy+0x2a>
f010597c:	b9 00 00 00 00       	mov    $0x0,%ecx
		*dst++ = *src;
f0105981:	0f b6 1a             	movzbl (%edx),%ebx
f0105984:	88 1c 08             	mov    %bl,(%eax,%ecx,1)
		// If strlen(src) < size, null-pad 'dst' out to 'size' chars
		if (*src != '\0')
			src++;
f0105987:	80 3a 01             	cmpb   $0x1,(%edx)
f010598a:	83 da ff             	sbb    $0xffffffff,%edx
strncpy(char *dst, const char *src, size_t size) {
	size_t i;
	char *ret;

	ret = dst;
	for (i = 0; i < size; i++) {
f010598d:	83 c1 01             	add    $0x1,%ecx
f0105990:	39 ce                	cmp    %ecx,%esi
f0105992:	77 ed                	ja     f0105981 <strncpy+0x17>
		// If strlen(src) < size, null-pad 'dst' out to 'size' chars
		if (*src != '\0')
			src++;
	}
	return ret;
}
f0105994:	5b                   	pop    %ebx
f0105995:	5e                   	pop    %esi
f0105996:	5d                   	pop    %ebp
f0105997:	c3                   	ret    

f0105998 <strlcpy>:

size_t
strlcpy(char *dst, const char *src, size_t size)
{
f0105998:	55                   	push   %ebp
f0105999:	89 e5                	mov    %esp,%ebp
f010599b:	56                   	push   %esi
f010599c:	53                   	push   %ebx
f010599d:	8b 75 08             	mov    0x8(%ebp),%esi
f01059a0:	8b 55 0c             	mov    0xc(%ebp),%edx
f01059a3:	8b 4d 10             	mov    0x10(%ebp),%ecx
	char *dst_in;

	dst_in = dst;
	if (size > 0) {
f01059a6:	89 f0                	mov    %esi,%eax
f01059a8:	85 c9                	test   %ecx,%ecx
f01059aa:	74 27                	je     f01059d3 <strlcpy+0x3b>
		while (--size > 0 && *src != '\0')
f01059ac:	83 e9 01             	sub    $0x1,%ecx
f01059af:	74 1d                	je     f01059ce <strlcpy+0x36>
f01059b1:	0f b6 1a             	movzbl (%edx),%ebx
f01059b4:	84 db                	test   %bl,%bl
f01059b6:	74 16                	je     f01059ce <strlcpy+0x36>
			*dst++ = *src++;
f01059b8:	88 18                	mov    %bl,(%eax)
f01059ba:	83 c0 01             	add    $0x1,%eax
{
	char *dst_in;

	dst_in = dst;
	if (size > 0) {
		while (--size > 0 && *src != '\0')
f01059bd:	83 e9 01             	sub    $0x1,%ecx
f01059c0:	74 0e                	je     f01059d0 <strlcpy+0x38>
			*dst++ = *src++;
f01059c2:	83 c2 01             	add    $0x1,%edx
{
	char *dst_in;

	dst_in = dst;
	if (size > 0) {
		while (--size > 0 && *src != '\0')
f01059c5:	0f b6 1a             	movzbl (%edx),%ebx
f01059c8:	84 db                	test   %bl,%bl
f01059ca:	75 ec                	jne    f01059b8 <strlcpy+0x20>
f01059cc:	eb 02                	jmp    f01059d0 <strlcpy+0x38>
f01059ce:	89 f0                	mov    %esi,%eax
			*dst++ = *src++;
		*dst = '\0';
f01059d0:	c6 00 00             	movb   $0x0,(%eax)
f01059d3:	29 f0                	sub    %esi,%eax
	}
	return dst - dst_in;
}
f01059d5:	5b                   	pop    %ebx
f01059d6:	5e                   	pop    %esi
f01059d7:	5d                   	pop    %ebp
f01059d8:	c3                   	ret    

f01059d9 <strcmp>:

int
strcmp(const char *p, const char *q)
{
f01059d9:	55                   	push   %ebp
f01059da:	89 e5                	mov    %esp,%ebp
f01059dc:	8b 4d 08             	mov    0x8(%ebp),%ecx
f01059df:	8b 55 0c             	mov    0xc(%ebp),%edx
	while (*p && *p == *q)
f01059e2:	0f b6 01             	movzbl (%ecx),%eax
f01059e5:	84 c0                	test   %al,%al
f01059e7:	74 15                	je     f01059fe <strcmp+0x25>
f01059e9:	3a 02                	cmp    (%edx),%al
f01059eb:	75 11                	jne    f01059fe <strcmp+0x25>
		p++, q++;
f01059ed:	83 c1 01             	add    $0x1,%ecx
f01059f0:	83 c2 01             	add    $0x1,%edx
}

int
strcmp(const char *p, const char *q)
{
	while (*p && *p == *q)
f01059f3:	0f b6 01             	movzbl (%ecx),%eax
f01059f6:	84 c0                	test   %al,%al
f01059f8:	74 04                	je     f01059fe <strcmp+0x25>
f01059fa:	3a 02                	cmp    (%edx),%al
f01059fc:	74 ef                	je     f01059ed <strcmp+0x14>
f01059fe:	0f b6 c0             	movzbl %al,%eax
f0105a01:	0f b6 12             	movzbl (%edx),%edx
f0105a04:	29 d0                	sub    %edx,%eax
		p++, q++;
	return (int) ((unsigned char) *p - (unsigned char) *q);
}
f0105a06:	5d                   	pop    %ebp
f0105a07:	c3                   	ret    

f0105a08 <strncmp>:

int
strncmp(const char *p, const char *q, size_t n)
{
f0105a08:	55                   	push   %ebp
f0105a09:	89 e5                	mov    %esp,%ebp
f0105a0b:	53                   	push   %ebx
f0105a0c:	8b 55 08             	mov    0x8(%ebp),%edx
f0105a0f:	8b 4d 0c             	mov    0xc(%ebp),%ecx
f0105a12:	8b 45 10             	mov    0x10(%ebp),%eax
	while (n > 0 && *p && *p == *q)
f0105a15:	85 c0                	test   %eax,%eax
f0105a17:	74 23                	je     f0105a3c <strncmp+0x34>
f0105a19:	0f b6 1a             	movzbl (%edx),%ebx
f0105a1c:	84 db                	test   %bl,%bl
f0105a1e:	74 24                	je     f0105a44 <strncmp+0x3c>
f0105a20:	3a 19                	cmp    (%ecx),%bl
f0105a22:	75 20                	jne    f0105a44 <strncmp+0x3c>
f0105a24:	83 e8 01             	sub    $0x1,%eax
f0105a27:	74 13                	je     f0105a3c <strncmp+0x34>
		n--, p++, q++;
f0105a29:	83 c2 01             	add    $0x1,%edx
f0105a2c:	83 c1 01             	add    $0x1,%ecx
}

int
strncmp(const char *p, const char *q, size_t n)
{
	while (n > 0 && *p && *p == *q)
f0105a2f:	0f b6 1a             	movzbl (%edx),%ebx
f0105a32:	84 db                	test   %bl,%bl
f0105a34:	74 0e                	je     f0105a44 <strncmp+0x3c>
f0105a36:	3a 19                	cmp    (%ecx),%bl
f0105a38:	74 ea                	je     f0105a24 <strncmp+0x1c>
f0105a3a:	eb 08                	jmp    f0105a44 <strncmp+0x3c>
f0105a3c:	b8 00 00 00 00       	mov    $0x0,%eax
		n--, p++, q++;
	if (n == 0)
		return 0;
	else
		return (int) ((unsigned char) *p - (unsigned char) *q);
}
f0105a41:	5b                   	pop    %ebx
f0105a42:	5d                   	pop    %ebp
f0105a43:	c3                   	ret    
	while (n > 0 && *p && *p == *q)
		n--, p++, q++;
	if (n == 0)
		return 0;
	else
		return (int) ((unsigned char) *p - (unsigned char) *q);
f0105a44:	0f b6 02             	movzbl (%edx),%eax
f0105a47:	0f b6 11             	movzbl (%ecx),%edx
f0105a4a:	29 d0                	sub    %edx,%eax
f0105a4c:	eb f3                	jmp    f0105a41 <strncmp+0x39>

f0105a4e <strchr>:

// Return a pointer to the first occurrence of 'c' in 's',
// or a null pointer if the string has no 'c'.
char *
strchr(const char *s, char c)
{
f0105a4e:	55                   	push   %ebp
f0105a4f:	89 e5                	mov    %esp,%ebp
f0105a51:	8b 45 08             	mov    0x8(%ebp),%eax
f0105a54:	0f b6 4d 0c          	movzbl 0xc(%ebp),%ecx
	for (; *s; s++)
f0105a58:	0f b6 10             	movzbl (%eax),%edx
f0105a5b:	84 d2                	test   %dl,%dl
f0105a5d:	74 15                	je     f0105a74 <strchr+0x26>
		if (*s == c)
f0105a5f:	38 ca                	cmp    %cl,%dl
f0105a61:	75 07                	jne    f0105a6a <strchr+0x1c>
f0105a63:	eb 14                	jmp    f0105a79 <strchr+0x2b>
f0105a65:	38 ca                	cmp    %cl,%dl
f0105a67:	90                   	nop
f0105a68:	74 0f                	je     f0105a79 <strchr+0x2b>
// Return a pointer to the first occurrence of 'c' in 's',
// or a null pointer if the string has no 'c'.
char *
strchr(const char *s, char c)
{
	for (; *s; s++)
f0105a6a:	83 c0 01             	add    $0x1,%eax
f0105a6d:	0f b6 10             	movzbl (%eax),%edx
f0105a70:	84 d2                	test   %dl,%dl
f0105a72:	75 f1                	jne    f0105a65 <strchr+0x17>
f0105a74:	b8 00 00 00 00       	mov    $0x0,%eax
		if (*s == c)
			return (char *) s;
	return 0;
}
f0105a79:	5d                   	pop    %ebp
f0105a7a:	c3                   	ret    

f0105a7b <strfind>:

// Return a pointer to the first occurrence of 'c' in 's',
// or a pointer to the string-ending null character if the string has no 'c'.
char *
strfind(const char *s, char c)
{
f0105a7b:	55                   	push   %ebp
f0105a7c:	89 e5                	mov    %esp,%ebp
f0105a7e:	8b 45 08             	mov    0x8(%ebp),%eax
f0105a81:	0f b6 4d 0c          	movzbl 0xc(%ebp),%ecx
	for (; *s; s++)
f0105a85:	0f b6 10             	movzbl (%eax),%edx
f0105a88:	84 d2                	test   %dl,%dl
f0105a8a:	74 18                	je     f0105aa4 <strfind+0x29>
		if (*s == c)
f0105a8c:	38 ca                	cmp    %cl,%dl
f0105a8e:	75 0a                	jne    f0105a9a <strfind+0x1f>
f0105a90:	eb 12                	jmp    f0105aa4 <strfind+0x29>
f0105a92:	38 ca                	cmp    %cl,%dl
f0105a94:	8d 74 26 00          	lea    0x0(%esi,%eiz,1),%esi
f0105a98:	74 0a                	je     f0105aa4 <strfind+0x29>
// Return a pointer to the first occurrence of 'c' in 's',
// or a pointer to the string-ending null character if the string has no 'c'.
char *
strfind(const char *s, char c)
{
	for (; *s; s++)
f0105a9a:	83 c0 01             	add    $0x1,%eax
f0105a9d:	0f b6 10             	movzbl (%eax),%edx
f0105aa0:	84 d2                	test   %dl,%dl
f0105aa2:	75 ee                	jne    f0105a92 <strfind+0x17>
		if (*s == c)
			break;
	return (char *) s;
}
f0105aa4:	5d                   	pop    %ebp
f0105aa5:	c3                   	ret    

f0105aa6 <memset>:

#if ASM
void *
memset(void *v, int c, size_t n)
{
f0105aa6:	55                   	push   %ebp
f0105aa7:	89 e5                	mov    %esp,%ebp
f0105aa9:	83 ec 0c             	sub    $0xc,%esp
f0105aac:	89 1c 24             	mov    %ebx,(%esp)
f0105aaf:	89 74 24 04          	mov    %esi,0x4(%esp)
f0105ab3:	89 7c 24 08          	mov    %edi,0x8(%esp)
f0105ab7:	8b 7d 08             	mov    0x8(%ebp),%edi
f0105aba:	8b 45 0c             	mov    0xc(%ebp),%eax
f0105abd:	8b 4d 10             	mov    0x10(%ebp),%ecx
	char *p;

	if (n == 0)
f0105ac0:	85 c9                	test   %ecx,%ecx
f0105ac2:	74 30                	je     f0105af4 <memset+0x4e>
		return v;
	if ((int)v%4 == 0 && n%4 == 0) {
f0105ac4:	f7 c7 03 00 00 00    	test   $0x3,%edi
f0105aca:	75 25                	jne    f0105af1 <memset+0x4b>
f0105acc:	f6 c1 03             	test   $0x3,%cl
f0105acf:	75 20                	jne    f0105af1 <memset+0x4b>
		c &= 0xFF;
f0105ad1:	0f b6 d0             	movzbl %al,%edx
		c = (c<<24)|(c<<16)|(c<<8)|c;
f0105ad4:	89 d3                	mov    %edx,%ebx
f0105ad6:	c1 e3 08             	shl    $0x8,%ebx
f0105ad9:	89 d6                	mov    %edx,%esi
f0105adb:	c1 e6 18             	shl    $0x18,%esi
f0105ade:	89 d0                	mov    %edx,%eax
f0105ae0:	c1 e0 10             	shl    $0x10,%eax
f0105ae3:	09 f0                	or     %esi,%eax
f0105ae5:	09 d0                	or     %edx,%eax
		asm volatile("cld; rep stosl\n"
f0105ae7:	09 d8                	or     %ebx,%eax
f0105ae9:	c1 e9 02             	shr    $0x2,%ecx
f0105aec:	fc                   	cld    
f0105aed:	f3 ab                	rep stos %eax,%es:(%edi)
{
	char *p;

	if (n == 0)
		return v;
	if ((int)v%4 == 0 && n%4 == 0) {
f0105aef:	eb 03                	jmp    f0105af4 <memset+0x4e>
		c = (c<<24)|(c<<16)|(c<<8)|c;
		asm volatile("cld; rep stosl\n"
			:: "D" (v), "a" (c), "c" (n/4)
			: "cc", "memory");
	} else
		asm volatile("cld; rep stosb\n"
f0105af1:	fc                   	cld    
f0105af2:	f3 aa                	rep stos %al,%es:(%edi)
			:: "D" (v), "a" (c), "c" (n)
			: "cc", "memory");
	return v;
}
f0105af4:	89 f8                	mov    %edi,%eax
f0105af6:	8b 1c 24             	mov    (%esp),%ebx
f0105af9:	8b 74 24 04          	mov    0x4(%esp),%esi
f0105afd:	8b 7c 24 08          	mov    0x8(%esp),%edi
f0105b01:	89 ec                	mov    %ebp,%esp
f0105b03:	5d                   	pop    %ebp
f0105b04:	c3                   	ret    

f0105b05 <memmove>:

void *
memmove(void *dst, const void *src, size_t n)
{
f0105b05:	55                   	push   %ebp
f0105b06:	89 e5                	mov    %esp,%ebp
f0105b08:	83 ec 08             	sub    $0x8,%esp
f0105b0b:	89 34 24             	mov    %esi,(%esp)
f0105b0e:	89 7c 24 04          	mov    %edi,0x4(%esp)
f0105b12:	8b 45 08             	mov    0x8(%ebp),%eax
f0105b15:	8b 4d 10             	mov    0x10(%ebp),%ecx
	const char *s;
	char *d;
	
	s = src;
f0105b18:	8b 75 0c             	mov    0xc(%ebp),%esi
	d = dst;
f0105b1b:	89 c7                	mov    %eax,%edi
	if (s < d && s + n > d) {
f0105b1d:	39 c6                	cmp    %eax,%esi
f0105b1f:	73 35                	jae    f0105b56 <memmove+0x51>
f0105b21:	8d 14 0e             	lea    (%esi,%ecx,1),%edx
f0105b24:	39 d0                	cmp    %edx,%eax
f0105b26:	73 2e                	jae    f0105b56 <memmove+0x51>
		s += n;
		d += n;
f0105b28:	01 cf                	add    %ecx,%edi
		if ((int)s%4 == 0 && (int)d%4 == 0 && n%4 == 0)
f0105b2a:	f6 c2 03             	test   $0x3,%dl
f0105b2d:	75 1b                	jne    f0105b4a <memmove+0x45>
f0105b2f:	f7 c7 03 00 00 00    	test   $0x3,%edi
f0105b35:	75 13                	jne    f0105b4a <memmove+0x45>
f0105b37:	f6 c1 03             	test   $0x3,%cl
f0105b3a:	75 0e                	jne    f0105b4a <memmove+0x45>
			asm volatile("std; rep movsl\n"
f0105b3c:	83 ef 04             	sub    $0x4,%edi
f0105b3f:	8d 72 fc             	lea    -0x4(%edx),%esi
f0105b42:	c1 e9 02             	shr    $0x2,%ecx
f0105b45:	fd                   	std    
f0105b46:	f3 a5                	rep movsl %ds:(%esi),%es:(%edi)
	s = src;
	d = dst;
	if (s < d && s + n > d) {
		s += n;
		d += n;
		if ((int)s%4 == 0 && (int)d%4 == 0 && n%4 == 0)
f0105b48:	eb 09                	jmp    f0105b53 <memmove+0x4e>
			asm volatile("std; rep movsl\n"
				:: "D" (d-4), "S" (s-4), "c" (n/4) : "cc", "memory");
		else
			asm volatile("std; rep movsb\n"
f0105b4a:	83 ef 01             	sub    $0x1,%edi
f0105b4d:	8d 72 ff             	lea    -0x1(%edx),%esi
f0105b50:	fd                   	std    
f0105b51:	f3 a4                	rep movsb %ds:(%esi),%es:(%edi)
				:: "D" (d-1), "S" (s-1), "c" (n) : "cc", "memory");
		// Some versions of GCC rely on DF being clear
		asm volatile("cld" ::: "cc");
f0105b53:	fc                   	cld    
	const char *s;
	char *d;
	
	s = src;
	d = dst;
	if (s < d && s + n > d) {
f0105b54:	eb 20                	jmp    f0105b76 <memmove+0x71>
			asm volatile("std; rep movsb\n"
				:: "D" (d-1), "S" (s-1), "c" (n) : "cc", "memory");
		// Some versions of GCC rely on DF being clear
		asm volatile("cld" ::: "cc");
	} else {
		if ((int)s%4 == 0 && (int)d%4 == 0 && n%4 == 0)
f0105b56:	f7 c6 03 00 00 00    	test   $0x3,%esi
f0105b5c:	75 15                	jne    f0105b73 <memmove+0x6e>
f0105b5e:	f7 c7 03 00 00 00    	test   $0x3,%edi
f0105b64:	75 0d                	jne    f0105b73 <memmove+0x6e>
f0105b66:	f6 c1 03             	test   $0x3,%cl
f0105b69:	75 08                	jne    f0105b73 <memmove+0x6e>
			asm volatile("cld; rep movsl\n"
f0105b6b:	c1 e9 02             	shr    $0x2,%ecx
f0105b6e:	fc                   	cld    
f0105b6f:	f3 a5                	rep movsl %ds:(%esi),%es:(%edi)
			asm volatile("std; rep movsb\n"
				:: "D" (d-1), "S" (s-1), "c" (n) : "cc", "memory");
		// Some versions of GCC rely on DF being clear
		asm volatile("cld" ::: "cc");
	} else {
		if ((int)s%4 == 0 && (int)d%4 == 0 && n%4 == 0)
f0105b71:	eb 03                	jmp    f0105b76 <memmove+0x71>
			asm volatile("cld; rep movsl\n"
				:: "D" (d), "S" (s), "c" (n/4) : "cc", "memory");
		else
			asm volatile("cld; rep movsb\n"
f0105b73:	fc                   	cld    
f0105b74:	f3 a4                	rep movsb %ds:(%esi),%es:(%edi)
				:: "D" (d), "S" (s), "c" (n) : "cc", "memory");
	}
	return dst;
}
f0105b76:	8b 34 24             	mov    (%esp),%esi
f0105b79:	8b 7c 24 04          	mov    0x4(%esp),%edi
f0105b7d:	89 ec                	mov    %ebp,%esp
f0105b7f:	5d                   	pop    %ebp
f0105b80:	c3                   	ret    

f0105b81 <memcpy>:

/* sigh - gcc emits references to this for structure assignments! */
/* it is *not* prototyped in inc/string.h - do not use directly. */
void *
memcpy(void *dst, void *src, size_t n)
{
f0105b81:	55                   	push   %ebp
f0105b82:	89 e5                	mov    %esp,%ebp
f0105b84:	83 ec 0c             	sub    $0xc,%esp
	return memmove(dst, src, n);
f0105b87:	8b 45 10             	mov    0x10(%ebp),%eax
f0105b8a:	89 44 24 08          	mov    %eax,0x8(%esp)
f0105b8e:	8b 45 0c             	mov    0xc(%ebp),%eax
f0105b91:	89 44 24 04          	mov    %eax,0x4(%esp)
f0105b95:	8b 45 08             	mov    0x8(%ebp),%eax
f0105b98:	89 04 24             	mov    %eax,(%esp)
f0105b9b:	e8 65 ff ff ff       	call   f0105b05 <memmove>
}
f0105ba0:	c9                   	leave  
f0105ba1:	c3                   	ret    

f0105ba2 <memcmp>:

int
memcmp(const void *v1, const void *v2, size_t n)
{
f0105ba2:	55                   	push   %ebp
f0105ba3:	89 e5                	mov    %esp,%ebp
f0105ba5:	57                   	push   %edi
f0105ba6:	56                   	push   %esi
f0105ba7:	53                   	push   %ebx
f0105ba8:	8b 75 08             	mov    0x8(%ebp),%esi
f0105bab:	8b 7d 0c             	mov    0xc(%ebp),%edi
f0105bae:	8b 4d 10             	mov    0x10(%ebp),%ecx
	const uint8_t *s1 = (const uint8_t *) v1;
	const uint8_t *s2 = (const uint8_t *) v2;

	while (n-- > 0) {
f0105bb1:	85 c9                	test   %ecx,%ecx
f0105bb3:	74 36                	je     f0105beb <memcmp+0x49>
		if (*s1 != *s2)
f0105bb5:	0f b6 06             	movzbl (%esi),%eax
f0105bb8:	0f b6 1f             	movzbl (%edi),%ebx
f0105bbb:	38 d8                	cmp    %bl,%al
f0105bbd:	74 20                	je     f0105bdf <memcmp+0x3d>
f0105bbf:	eb 14                	jmp    f0105bd5 <memcmp+0x33>
f0105bc1:	0f b6 44 16 01       	movzbl 0x1(%esi,%edx,1),%eax
f0105bc6:	0f b6 5c 17 01       	movzbl 0x1(%edi,%edx,1),%ebx
f0105bcb:	83 c2 01             	add    $0x1,%edx
f0105bce:	83 e9 01             	sub    $0x1,%ecx
f0105bd1:	38 d8                	cmp    %bl,%al
f0105bd3:	74 12                	je     f0105be7 <memcmp+0x45>
			return (int) *s1 - (int) *s2;
f0105bd5:	0f b6 c0             	movzbl %al,%eax
f0105bd8:	0f b6 db             	movzbl %bl,%ebx
f0105bdb:	29 d8                	sub    %ebx,%eax
f0105bdd:	eb 11                	jmp    f0105bf0 <memcmp+0x4e>
memcmp(const void *v1, const void *v2, size_t n)
{
	const uint8_t *s1 = (const uint8_t *) v1;
	const uint8_t *s2 = (const uint8_t *) v2;

	while (n-- > 0) {
f0105bdf:	83 e9 01             	sub    $0x1,%ecx
f0105be2:	ba 00 00 00 00       	mov    $0x0,%edx
f0105be7:	85 c9                	test   %ecx,%ecx
f0105be9:	75 d6                	jne    f0105bc1 <memcmp+0x1f>
f0105beb:	b8 00 00 00 00       	mov    $0x0,%eax
			return (int) *s1 - (int) *s2;
		s1++, s2++;
	}

	return 0;
}
f0105bf0:	5b                   	pop    %ebx
f0105bf1:	5e                   	pop    %esi
f0105bf2:	5f                   	pop    %edi
f0105bf3:	5d                   	pop    %ebp
f0105bf4:	c3                   	ret    

f0105bf5 <memfind>:

void *
memfind(const void *s, int c, size_t n)
{
f0105bf5:	55                   	push   %ebp
f0105bf6:	89 e5                	mov    %esp,%ebp
f0105bf8:	8b 45 08             	mov    0x8(%ebp),%eax
	const void *ends = (const char *) s + n;
f0105bfb:	89 c2                	mov    %eax,%edx
f0105bfd:	03 55 10             	add    0x10(%ebp),%edx
	for (; s < ends; s++)
f0105c00:	39 d0                	cmp    %edx,%eax
f0105c02:	73 15                	jae    f0105c19 <memfind+0x24>
		if (*(const unsigned char *) s == (unsigned char) c)
f0105c04:	0f b6 4d 0c          	movzbl 0xc(%ebp),%ecx
f0105c08:	38 08                	cmp    %cl,(%eax)
f0105c0a:	75 06                	jne    f0105c12 <memfind+0x1d>
f0105c0c:	eb 0b                	jmp    f0105c19 <memfind+0x24>
f0105c0e:	38 08                	cmp    %cl,(%eax)
f0105c10:	74 07                	je     f0105c19 <memfind+0x24>

void *
memfind(const void *s, int c, size_t n)
{
	const void *ends = (const char *) s + n;
	for (; s < ends; s++)
f0105c12:	83 c0 01             	add    $0x1,%eax
f0105c15:	39 c2                	cmp    %eax,%edx
f0105c17:	77 f5                	ja     f0105c0e <memfind+0x19>
		if (*(const unsigned char *) s == (unsigned char) c)
			break;
	return (void *) s;
}
f0105c19:	5d                   	pop    %ebp
f0105c1a:	c3                   	ret    

f0105c1b <strtol>:

long
strtol(const char *s, char **endptr, int base)
{
f0105c1b:	55                   	push   %ebp
f0105c1c:	89 e5                	mov    %esp,%ebp
f0105c1e:	57                   	push   %edi
f0105c1f:	56                   	push   %esi
f0105c20:	53                   	push   %ebx
f0105c21:	83 ec 04             	sub    $0x4,%esp
f0105c24:	8b 55 08             	mov    0x8(%ebp),%edx
f0105c27:	8b 5d 10             	mov    0x10(%ebp),%ebx
	int neg = 0;
	long val = 0;

	// gobble initial whitespace
	while (*s == ' ' || *s == '\t')
f0105c2a:	0f b6 02             	movzbl (%edx),%eax
f0105c2d:	3c 20                	cmp    $0x20,%al
f0105c2f:	74 04                	je     f0105c35 <strtol+0x1a>
f0105c31:	3c 09                	cmp    $0x9,%al
f0105c33:	75 0e                	jne    f0105c43 <strtol+0x28>
		s++;
f0105c35:	83 c2 01             	add    $0x1,%edx
{
	int neg = 0;
	long val = 0;

	// gobble initial whitespace
	while (*s == ' ' || *s == '\t')
f0105c38:	0f b6 02             	movzbl (%edx),%eax
f0105c3b:	3c 20                	cmp    $0x20,%al
f0105c3d:	74 f6                	je     f0105c35 <strtol+0x1a>
f0105c3f:	3c 09                	cmp    $0x9,%al
f0105c41:	74 f2                	je     f0105c35 <strtol+0x1a>
		s++;

	// plus/minus sign
	if (*s == '+')
f0105c43:	3c 2b                	cmp    $0x2b,%al
f0105c45:	75 0c                	jne    f0105c53 <strtol+0x38>
		s++;
f0105c47:	83 c2 01             	add    $0x1,%edx
f0105c4a:	c7 45 f0 00 00 00 00 	movl   $0x0,-0x10(%ebp)
f0105c51:	eb 15                	jmp    f0105c68 <strtol+0x4d>
	else if (*s == '-')
f0105c53:	c7 45 f0 00 00 00 00 	movl   $0x0,-0x10(%ebp)
f0105c5a:	3c 2d                	cmp    $0x2d,%al
f0105c5c:	75 0a                	jne    f0105c68 <strtol+0x4d>
		s++, neg = 1;
f0105c5e:	83 c2 01             	add    $0x1,%edx
f0105c61:	c7 45 f0 01 00 00 00 	movl   $0x1,-0x10(%ebp)

	// hex or octal base prefix
	if ((base == 0 || base == 16) && (s[0] == '0' && s[1] == 'x'))
f0105c68:	85 db                	test   %ebx,%ebx
f0105c6a:	0f 94 c0             	sete   %al
f0105c6d:	74 05                	je     f0105c74 <strtol+0x59>
f0105c6f:	83 fb 10             	cmp    $0x10,%ebx
f0105c72:	75 18                	jne    f0105c8c <strtol+0x71>
f0105c74:	80 3a 30             	cmpb   $0x30,(%edx)
f0105c77:	75 13                	jne    f0105c8c <strtol+0x71>
f0105c79:	80 7a 01 78          	cmpb   $0x78,0x1(%edx)
f0105c7d:	8d 76 00             	lea    0x0(%esi),%esi
f0105c80:	75 0a                	jne    f0105c8c <strtol+0x71>
		s += 2, base = 16;
f0105c82:	83 c2 02             	add    $0x2,%edx
f0105c85:	bb 10 00 00 00       	mov    $0x10,%ebx
		s++;
	else if (*s == '-')
		s++, neg = 1;

	// hex or octal base prefix
	if ((base == 0 || base == 16) && (s[0] == '0' && s[1] == 'x'))
f0105c8a:	eb 15                	jmp    f0105ca1 <strtol+0x86>
		s += 2, base = 16;
	else if (base == 0 && s[0] == '0')
f0105c8c:	84 c0                	test   %al,%al
f0105c8e:	66 90                	xchg   %ax,%ax
f0105c90:	74 0f                	je     f0105ca1 <strtol+0x86>
f0105c92:	bb 0a 00 00 00       	mov    $0xa,%ebx
f0105c97:	80 3a 30             	cmpb   $0x30,(%edx)
f0105c9a:	75 05                	jne    f0105ca1 <strtol+0x86>
		s++, base = 8;
f0105c9c:	83 c2 01             	add    $0x1,%edx
f0105c9f:	b3 08                	mov    $0x8,%bl
		s++, neg = 1;

	// hex or octal base prefix
	if ((base == 0 || base == 16) && (s[0] == '0' && s[1] == 'x'))
		s += 2, base = 16;
	else if (base == 0 && s[0] == '0')
f0105ca1:	b8 00 00 00 00       	mov    $0x0,%eax
f0105ca6:	89 de                	mov    %ebx,%esi

	// digits
	while (1) {
		int dig;

		if (*s >= '0' && *s <= '9')
f0105ca8:	0f b6 0a             	movzbl (%edx),%ecx
f0105cab:	89 cf                	mov    %ecx,%edi
f0105cad:	8d 59 d0             	lea    -0x30(%ecx),%ebx
f0105cb0:	80 fb 09             	cmp    $0x9,%bl
f0105cb3:	77 08                	ja     f0105cbd <strtol+0xa2>
			dig = *s - '0';
f0105cb5:	0f be c9             	movsbl %cl,%ecx
f0105cb8:	83 e9 30             	sub    $0x30,%ecx
f0105cbb:	eb 1e                	jmp    f0105cdb <strtol+0xc0>
		else if (*s >= 'a' && *s <= 'z')
f0105cbd:	8d 5f 9f             	lea    -0x61(%edi),%ebx
f0105cc0:	80 fb 19             	cmp    $0x19,%bl
f0105cc3:	77 08                	ja     f0105ccd <strtol+0xb2>
			dig = *s - 'a' + 10;
f0105cc5:	0f be c9             	movsbl %cl,%ecx
f0105cc8:	83 e9 57             	sub    $0x57,%ecx
f0105ccb:	eb 0e                	jmp    f0105cdb <strtol+0xc0>
		else if (*s >= 'A' && *s <= 'Z')
f0105ccd:	8d 5f bf             	lea    -0x41(%edi),%ebx
f0105cd0:	80 fb 19             	cmp    $0x19,%bl
f0105cd3:	77 15                	ja     f0105cea <strtol+0xcf>
			dig = *s - 'A' + 10;
f0105cd5:	0f be c9             	movsbl %cl,%ecx
f0105cd8:	83 e9 37             	sub    $0x37,%ecx
		else
			break;
		if (dig >= base)
f0105cdb:	39 f1                	cmp    %esi,%ecx
f0105cdd:	7d 0b                	jge    f0105cea <strtol+0xcf>
			break;
		s++, val = (val * base) + dig;
f0105cdf:	83 c2 01             	add    $0x1,%edx
f0105ce2:	0f af c6             	imul   %esi,%eax
f0105ce5:	8d 04 01             	lea    (%ecx,%eax,1),%eax
		// we don't properly detect overflow!
	}
f0105ce8:	eb be                	jmp    f0105ca8 <strtol+0x8d>
f0105cea:	89 c1                	mov    %eax,%ecx

	if (endptr)
f0105cec:	83 7d 0c 00          	cmpl   $0x0,0xc(%ebp)
f0105cf0:	74 05                	je     f0105cf7 <strtol+0xdc>
		*endptr = (char *) s;
f0105cf2:	8b 5d 0c             	mov    0xc(%ebp),%ebx
f0105cf5:	89 13                	mov    %edx,(%ebx)
	return (neg ? -val : val);
f0105cf7:	89 ca                	mov    %ecx,%edx
f0105cf9:	f7 da                	neg    %edx
f0105cfb:	83 7d f0 00          	cmpl   $0x0,-0x10(%ebp)
f0105cff:	0f 45 c2             	cmovne %edx,%eax
}
f0105d02:	83 c4 04             	add    $0x4,%esp
f0105d05:	5b                   	pop    %ebx
f0105d06:	5e                   	pop    %esi
f0105d07:	5f                   	pop    %edi
f0105d08:	5d                   	pop    %ebp
f0105d09:	c3                   	ret    
	...

f0105d0c <e100_reset_device>:
/**
 * This function resets the device by sending a 0L to PORT.
 **/

void
e100_reset_device() {
f0105d0c:	55                   	push   %ebp
f0105d0d:	89 e5                	mov    %esp,%ebp
}

static __inline void
outl(int port, uint32_t data)
{
	__asm __volatile("outl %0,%w1" : : "a" (data), "d" (port));
f0105d0f:	8b 15 18 00 2d f0    	mov    0xf02d0018,%edx
f0105d15:	83 c2 08             	add    $0x8,%edx
f0105d18:	b8 00 00 00 00       	mov    $0x0,%eax
f0105d1d:	ef                   	out    %eax,(%dx)
    // Write 0 to PORT for resetting the device.
	outl(nd.reg_base[1]+0x8, 0);
}
f0105d1e:	5d                   	pop    %ebp
f0105d1f:	c3                   	ret    

f0105d20 <e100_ns_send>:
    outb(nd.reg_base[1]+0x2, E100_SCB_RUC_NOOP);
    //outl(nd.reg_base[1]+0x4, PADDR(&e100_rx_ring));
}

int
e100_ns_send(void *pkt, int len) {
f0105d20:	55                   	push   %ebp
f0105d21:	89 e5                	mov    %esp,%ebp
f0105d23:	53                   	push   %ebx
f0105d24:	83 ec 14             	sub    $0x14,%esp
f0105d27:	8b 5d 0c             	mov    0xc(%ebp),%ebx
    int i=0;
    for (i=0;i<E100_TX_RING_SIZE;i++) {
        //cprintf("\ni=%x status=%x\n", i, e100_tx_ring[i].status); 
        if (E100_SCB_STATUS_CBIT_SET(e100_tx_ring[i].status)) {
f0105d2a:	0f b7 15 60 00 2d f0 	movzwl 0xf02d0060,%edx
f0105d31:	b8 f0 ff ff ff       	mov    $0xfffffff0,%eax
f0105d36:	66 85 d2             	test   %dx,%dx
f0105d39:	79 4f                	jns    f0105d8a <e100_ns_send+0x6a>
            memmove((void *)e100_tx_ring[i].buffer, pkt, len);
f0105d3b:	89 5c 24 08          	mov    %ebx,0x8(%esp)
f0105d3f:	8b 45 08             	mov    0x8(%ebp),%eax
f0105d42:	89 44 24 04          	mov    %eax,0x4(%esp)
f0105d46:	c7 04 24 70 00 2d f0 	movl   $0xf02d0070,(%esp)
f0105d4d:	e8 b3 fd ff ff       	call   f0105b05 <memmove>
            e100_tx_ring[i].tcb_info    = E100_TCB_CONST_INFO_WORD(len);
f0105d52:	81 e3 ff 3f 00 00    	and    $0x3fff,%ebx
f0105d58:	81 cb 00 00 e0 00    	or     $0xe00000,%ebx
f0105d5e:	89 1d 6c 00 2d f0    	mov    %ebx,0xf02d006c
            e100_tx_ring[i].cmd         = E100_TCB_CMD_TRANSMIT|E100_SCB_CMD_ELBIT;
f0105d64:	66 c7 05 62 00 2d f0 	movw   $0x8004,0xf02d0062
f0105d6b:	04 80 
            e100_tx_ring[i].status      = 0;
f0105d6d:	66 c7 05 60 00 2d f0 	movw   $0x0,0xf02d0060
f0105d74:	00 00 
}

static __inline void
outb(int port, uint8_t data)
{
	__asm __volatile("outb %0,%w1" : : "a" (data), "d" (port));
f0105d76:	8b 15 18 00 2d f0    	mov    0xf02d0018,%edx
f0105d7c:	83 c2 02             	add    $0x2,%edx
f0105d7f:	b8 10 00 00 00       	mov    $0x10,%eax
f0105d84:	ee                   	out    %al,(%dx)
f0105d85:	b8 00 00 00 00       	mov    $0x0,%eax
            outb(nd.reg_base[1]+0x2, E100_SCB_CUC_START);
            return 0;
        }
    }
    return -E_NO_FREE_BUF;
}
f0105d8a:	83 c4 14             	add    $0x14,%esp
f0105d8d:	5b                   	pop    %ebx
f0105d8e:	5d                   	pop    %ebp
f0105d8f:	c3                   	ret    

f0105d90 <e100_ns_recv>:

int
e100_ns_recv(void *pkt, int len) {
f0105d90:	55                   	push   %ebp
f0105d91:	89 e5                	mov    %esp,%ebp
f0105d93:	53                   	push   %ebx
f0105d94:	83 ec 14             	sub    $0x14,%esp
    int i=0;
    //outb(nd.reg_base[1]+0x2, E100_SCB_RUC_START);
    for (i=0;i<E100_RX_RING_SIZE;i++) {
        if (E100_SCB_STATUS_CBIT_SET(e100_rx_ring[i].status)
f0105d97:	0f b7 05 00 10 2d f0 	movzwl 0xf02d1000,%eax
f0105d9e:	66 85 c0             	test   %ax,%ax
f0105da1:	79 46                	jns    f0105de9 <e100_ns_recv+0x59>
            && E100_RFD_FBIT(e100_rx_ring[i].rfd_info)
f0105da3:	8b 1d 0c 10 2d f0    	mov    0xf02d100c,%ebx
int
e100_ns_recv(void *pkt, int len) {
    int i=0;
    //outb(nd.reg_base[1]+0x2, E100_SCB_RUC_START);
    for (i=0;i<E100_RX_RING_SIZE;i++) {
        if (E100_SCB_STATUS_CBIT_SET(e100_rx_ring[i].status)
f0105da9:	89 d8                	mov    %ebx,%eax
f0105dab:	25 00 c0 00 00       	and    $0xc000,%eax
f0105db0:	3d 00 c0 00 00       	cmp    $0xc000,%eax
f0105db5:	75 32                	jne    f0105de9 <e100_ns_recv+0x59>
            && E100_RFD_FBIT(e100_rx_ring[i].rfd_info)
            && E100_RFD_EOF(e100_rx_ring[i].rfd_info)) {
            int length  = E100_RFD_COUNT(e100_rx_ring[i].rfd_info);
f0105db7:	81 e3 ff 3f 00 00    	and    $0x3fff,%ebx
            //cprintf("\nStatus: %x Info: %x\n", e100_rx_ring[i].status, e100_rx_ring[i].rfd_info);
            //cprintf("\nReceived: Len: %x\n", length);
            memmove(pkt, (void *)e100_rx_ring[i].rfa, length);
f0105dbd:	89 5c 24 08          	mov    %ebx,0x8(%esp)
f0105dc1:	c7 44 24 04 10 10 2d 	movl   $0xf02d1010,0x4(%esp)
f0105dc8:	f0 
f0105dc9:	8b 45 08             	mov    0x8(%ebp),%eax
f0105dcc:	89 04 24             	mov    %eax,(%esp)
f0105dcf:	e8 31 fd ff ff       	call   f0105b05 <memmove>
            e100_rx_ring[i].rfd_info    = E100_RFD_COUNT_INFO_WORD(0);
f0105dd4:	c7 05 0c 10 2d f0 00 	movl   $0x6400000,0xf02d100c
f0105ddb:	00 40 06 
            e100_rx_ring[i].status      = 0;
f0105dde:	66 c7 05 00 10 2d f0 	movw   $0x0,0xf02d1000
f0105de5:	00 00 
            /*if (e100_rx_ring[i].cmd & E100_SCB_CMD_ELBIT)
                outb(nd.reg_base[1]+0x2, E100_SCB_RUC_START);*/
            return length;
f0105de7:	eb 55                	jmp    f0105e3e <e100_ns_recv+0xae>
        }
        if (E100_SCB_RUS_NORES(inb(nd.reg_base[1]))) {
f0105de9:	8b 0d 18 00 2d f0    	mov    0xf02d0018,%ecx

static __inline uint8_t
inb(int port)
{
	uint8_t data;
	__asm __volatile("inb %w1,%0" : "=a" (data) : "d" (port));
f0105def:	89 ca                	mov    %ecx,%edx
f0105df1:	ec                   	in     (%dx),%al
f0105df2:	bb ef ff ff ff       	mov    $0xffffffef,%ebx
f0105df7:	a8 04                	test   $0x4,%al
f0105df9:	74 43                	je     f0105e3e <e100_ns_recv+0xae>
            outl(nd.reg_base[1]+0x4, PADDR(&e100_rx_ring));
f0105dfb:	b8 00 10 2d f0       	mov    $0xf02d1000,%eax
f0105e00:	3d ff ff ff ef       	cmp    $0xefffffff,%eax
f0105e05:	77 20                	ja     f0105e27 <e100_ns_recv+0x97>
f0105e07:	89 44 24 0c          	mov    %eax,0xc(%esp)
f0105e0b:	c7 44 24 08 d0 70 10 	movl   $0xf01070d0,0x8(%esp)
f0105e12:	f0 
f0105e13:	c7 44 24 04 71 00 00 	movl   $0x71,0x4(%esp)
f0105e1a:	00 
f0105e1b:	c7 04 24 7b 81 10 f0 	movl   $0xf010817b,(%esp)
f0105e22:	e8 5e a2 ff ff       	call   f0100085 <_panic>
}

static __inline void
outl(int port, uint32_t data)
{
	__asm __volatile("outl %0,%w1" : : "a" (data), "d" (port));
f0105e27:	05 00 00 00 10       	add    $0x10000000,%eax
f0105e2c:	8d 51 04             	lea    0x4(%ecx),%edx
f0105e2f:	ef                   	out    %eax,(%dx)
}

static __inline void
outb(int port, uint8_t data)
{
	__asm __volatile("outb %0,%w1" : : "a" (data), "d" (port));
f0105e30:	8d 51 02             	lea    0x2(%ecx),%edx
f0105e33:	b8 01 00 00 00       	mov    $0x1,%eax
f0105e38:	ee                   	out    %al,(%dx)
f0105e39:	bb ef ff ff ff       	mov    $0xffffffef,%ebx
            outb(nd.reg_base[1]+0x2, E100_SCB_RUC_START);
        }
    }
    return -E_NO_DATA;
}
f0105e3e:	89 d8                	mov    %ebx,%eax
f0105e40:	83 c4 14             	add    $0x14,%esp
f0105e43:	5b                   	pop    %ebx
f0105e44:	5d                   	pop    %ebp
f0105e45:	c3                   	ret    

f0105e46 <e100_init_rx_ring>:
    outb(nd.reg_base[1]+0x2, E100_SCB_CUC_NOOP);
    outb(nd.reg_base[1]+0x2, E100_SCB_CUC_START);
}

void
e100_init_rx_ring() {
f0105e46:	55                   	push   %ebp
f0105e47:	89 e5                	mov    %esp,%ebp
f0105e49:	83 ec 18             	sub    $0x18,%esp
    int i=0;
    memset(&e100_rx_ring, 0, sizeof(e100_rx_ring));
f0105e4c:	c7 44 24 08 00 10 00 	movl   $0x1000,0x8(%esp)
f0105e53:	00 
f0105e54:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
f0105e5b:	00 
f0105e5c:	c7 04 24 00 10 2d f0 	movl   $0xf02d1000,(%esp)
f0105e63:	e8 3e fc ff ff       	call   f0105aa6 <memset>

    //Initialize receive buffers.
    for (i=0;i<E100_RX_RING_SIZE;i++) {
        e100_rx_ring[i].cmd         = 0x3;//|E100_SCB_RX_INTR;
f0105e68:	66 c7 05 02 10 2d f0 	movw   $0x3,0xf02d1002
f0105e6f:	03 00 
        e100_rx_ring[i].status      = 0;
f0105e71:	66 c7 05 00 10 2d f0 	movw   $0x0,0xf02d1000
f0105e78:	00 00 
        e100_rx_ring[i].link        = PADDR(&e100_rx_ring[(i+1)%E100_RX_RING_SIZE]);
f0105e7a:	b8 00 10 2d f0       	mov    $0xf02d1000,%eax
f0105e7f:	3d ff ff ff ef       	cmp    $0xefffffff,%eax
f0105e84:	77 20                	ja     f0105ea6 <e100_init_rx_ring+0x60>
f0105e86:	89 44 24 0c          	mov    %eax,0xc(%esp)
f0105e8a:	c7 44 24 08 d0 70 10 	movl   $0xf01070d0,0x8(%esp)
f0105e91:	f0 
f0105e92:	c7 44 24 04 40 00 00 	movl   $0x40,0x4(%esp)
f0105e99:	00 
f0105e9a:	c7 04 24 7b 81 10 f0 	movl   $0xf010817b,(%esp)
f0105ea1:	e8 df a1 ff ff       	call   f0100085 <_panic>
f0105ea6:	05 00 00 00 10       	add    $0x10000000,%eax
f0105eab:	a3 04 10 2d f0       	mov    %eax,0xf02d1004
        e100_rx_ring[i].rfd_info    = E100_RFD_COUNT_INFO_WORD(0); 
f0105eb0:	c7 05 0c 10 2d f0 00 	movl   $0x6400000,0xf02d100c
f0105eb7:	00 40 06 
    }
    e100_rx_ring[E100_RX_RING_SIZE-1].cmd   |= E100_SCB_CMD_ELBIT;
f0105eba:	66 c7 05 02 10 2d f0 	movw   $0x8003,0xf02d1002
f0105ec1:	03 80 

    // Stuff e100_rx_ring into the E100 registers.
    //outl(nd.reg_base[1]+0x14, E100_RX_BUFFER_SIZE);
    outl(nd.reg_base[1]+0x4, PADDR(&e100_rx_ring));
f0105ec3:	8b 0d 18 00 2d f0    	mov    0xf02d0018,%ecx
}

static __inline void
outl(int port, uint32_t data)
{
	__asm __volatile("outl %0,%w1" : : "a" (data), "d" (port));
f0105ec9:	8d 51 04             	lea    0x4(%ecx),%edx
f0105ecc:	ef                   	out    %eax,(%dx)
    outb(nd.reg_base[1]+0x2, E100_SCB_RUC_START);
f0105ecd:	8d 51 02             	lea    0x2(%ecx),%edx
}

static __inline void
outb(int port, uint8_t data)
{
	__asm __volatile("outb %0,%w1" : : "a" (data), "d" (port));
f0105ed0:	b8 01 00 00 00       	mov    $0x1,%eax
f0105ed5:	ee                   	out    %al,(%dx)
f0105ed6:	b8 00 00 00 00       	mov    $0x0,%eax
f0105edb:	ee                   	out    %al,(%dx)
    outb(nd.reg_base[1]+0x2, E100_SCB_RUC_NOOP);
    //outl(nd.reg_base[1]+0x4, PADDR(&e100_rx_ring));
}
f0105edc:	c9                   	leave  
f0105edd:	c3                   	ret    

f0105ede <e100_init_tx_ring>:
    // Write 0 to PORT for resetting the device.
	outl(nd.reg_base[1]+0x8, 0);
}

void
e100_init_tx_ring() {
f0105ede:	55                   	push   %ebp
f0105edf:	89 e5                	mov    %esp,%ebp
f0105ee1:	83 ec 18             	sub    $0x18,%esp
    int i=0;
    memset(&e100_tx_ring, 0, sizeof(e100_tx_ring));
f0105ee4:	c7 44 24 08 50 06 00 	movl   $0x650,0x8(%esp)
f0105eeb:	00 
f0105eec:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
f0105ef3:	00 
f0105ef4:	c7 04 24 60 00 2d f0 	movl   $0xf02d0060,(%esp)
f0105efb:	e8 a6 fb ff ff       	call   f0105aa6 <memset>

    // Initialize transmit buffers.
    for (i=0;i<E100_TX_RING_SIZE;i++) {
        e100_tx_ring[i].cmd         = E100_SCB_CMD_ELBIT;
f0105f00:	66 c7 05 62 00 2d f0 	movw   $0x8000,0xf02d0062
f0105f07:	00 80 
        e100_tx_ring[i].link        = PADDR(&e100_tx_ring[(i+1)%E100_TX_RING_SIZE]);
f0105f09:	b8 60 00 2d f0       	mov    $0xf02d0060,%eax
f0105f0e:	3d ff ff ff ef       	cmp    $0xefffffff,%eax
f0105f13:	77 20                	ja     f0105f35 <e100_init_tx_ring+0x57>
f0105f15:	89 44 24 0c          	mov    %eax,0xc(%esp)
f0105f19:	c7 44 24 08 d0 70 10 	movl   $0xf01070d0,0x8(%esp)
f0105f20:	f0 
f0105f21:	c7 44 24 04 2b 00 00 	movl   $0x2b,0x4(%esp)
f0105f28:	00 
f0105f29:	c7 04 24 7b 81 10 f0 	movl   $0xf010817b,(%esp)
f0105f30:	e8 50 a1 ff ff       	call   f0100085 <_panic>
f0105f35:	05 00 00 00 10       	add    $0x10000000,%eax
f0105f3a:	a3 64 00 2d f0       	mov    %eax,0xf02d0064
        e100_tx_ring[i].tbd_array   = 0xFFFFFFFF;
f0105f3f:	c7 05 68 00 2d f0 ff 	movl   $0xffffffff,0xf02d0068
f0105f46:	ff ff ff 
        e100_tx_ring[i].tcb_info    = E100_TCB_CONST_INFO_WORD(0); 
f0105f49:	c7 05 6c 00 2d f0 00 	movl   $0xe00000,0xf02d006c
f0105f50:	00 e0 00 
    }

    // Stuff e100_tx_ring into the E100 registers.
    outl(nd.reg_base[1]+0x4, PADDR(&e100_tx_ring));
f0105f53:	8b 0d 18 00 2d f0    	mov    0xf02d0018,%ecx
}

static __inline void
outl(int port, uint32_t data)
{
	__asm __volatile("outl %0,%w1" : : "a" (data), "d" (port));
f0105f59:	8d 51 04             	lea    0x4(%ecx),%edx
f0105f5c:	ef                   	out    %eax,(%dx)
    outb(nd.reg_base[1]+0x2, E100_SCB_CUC_LOAD_BASE);
f0105f5d:	8d 51 02             	lea    0x2(%ecx),%edx
}

static __inline void
outb(int port, uint8_t data)
{
	__asm __volatile("outb %0,%w1" : : "a" (data), "d" (port));
f0105f60:	b8 60 00 00 00       	mov    $0x60,%eax
f0105f65:	ee                   	out    %al,(%dx)
f0105f66:	b8 00 00 00 00       	mov    $0x0,%eax
f0105f6b:	ee                   	out    %al,(%dx)
f0105f6c:	b8 10 00 00 00       	mov    $0x10,%eax
f0105f71:	ee                   	out    %al,(%dx)
    outb(nd.reg_base[1]+0x2, E100_SCB_CUC_NOOP);
    outb(nd.reg_base[1]+0x2, E100_SCB_CUC_START);
}
f0105f72:	c9                   	leave  
f0105f73:	c3                   	ret    
	...

f0105f80 <pci_attach_match>:
}

static int __attribute__((warn_unused_result))
pci_attach_match(uint32_t key1, uint32_t key2,
		 struct pci_driver *list, struct pci_func *pcif)
{
f0105f80:	55                   	push   %ebp
f0105f81:	89 e5                	mov    %esp,%ebp
f0105f83:	57                   	push   %edi
f0105f84:	56                   	push   %esi
f0105f85:	53                   	push   %ebx
f0105f86:	83 ec 3c             	sub    $0x3c,%esp
f0105f89:	89 c7                	mov    %eax,%edi
f0105f8b:	89 55 e4             	mov    %edx,-0x1c(%ebp)
f0105f8e:	89 ce                	mov    %ecx,%esi
	uint32_t i;

	for (i = 0; list[i].attachfn; i++) {
f0105f90:	8b 41 08             	mov    0x8(%ecx),%eax
f0105f93:	85 c0                	test   %eax,%eax
f0105f95:	74 4d                	je     f0105fe4 <pci_attach_match+0x64>
f0105f97:	8d 59 0c             	lea    0xc(%ecx),%ebx
		if (list[i].key1 == key1 && list[i].key2 == key2) {
f0105f9a:	39 3e                	cmp    %edi,(%esi)
f0105f9c:	75 3a                	jne    f0105fd8 <pci_attach_match+0x58>
f0105f9e:	8b 55 e4             	mov    -0x1c(%ebp),%edx
f0105fa1:	39 56 04             	cmp    %edx,0x4(%esi)
f0105fa4:	75 32                	jne    f0105fd8 <pci_attach_match+0x58>
			int r = list[i].attachfn(pcif);
f0105fa6:	8b 55 08             	mov    0x8(%ebp),%edx
f0105fa9:	89 14 24             	mov    %edx,(%esp)
f0105fac:	ff d0                	call   *%eax
			if (r > 0)
f0105fae:	85 c0                	test   %eax,%eax
f0105fb0:	7f 37                	jg     f0105fe9 <pci_attach_match+0x69>
				return r;
			if (r < 0)
f0105fb2:	85 c0                	test   %eax,%eax
f0105fb4:	79 22                	jns    f0105fd8 <pci_attach_match+0x58>
				cprintf("pci_attach_match: attaching "
f0105fb6:	89 44 24 10          	mov    %eax,0x10(%esp)
f0105fba:	8b 46 08             	mov    0x8(%esi),%eax
f0105fbd:	89 44 24 0c          	mov    %eax,0xc(%esp)
f0105fc1:	8b 45 e4             	mov    -0x1c(%ebp),%eax
f0105fc4:	89 44 24 08          	mov    %eax,0x8(%esp)
f0105fc8:	89 7c 24 04          	mov    %edi,0x4(%esp)
f0105fcc:	c7 04 24 88 81 10 f0 	movl   $0xf0108188,(%esp)
f0105fd3:	e8 07 da ff ff       	call   f01039df <cprintf>
f0105fd8:	89 de                	mov    %ebx,%esi
pci_attach_match(uint32_t key1, uint32_t key2,
		 struct pci_driver *list, struct pci_func *pcif)
{
	uint32_t i;

	for (i = 0; list[i].attachfn; i++) {
f0105fda:	8b 43 08             	mov    0x8(%ebx),%eax
f0105fdd:	83 c3 0c             	add    $0xc,%ebx
f0105fe0:	85 c0                	test   %eax,%eax
f0105fe2:	75 b6                	jne    f0105f9a <pci_attach_match+0x1a>
f0105fe4:	b8 00 00 00 00       	mov    $0x0,%eax
					"%x.%x (%p): e\n",
					key1, key2, list[i].attachfn, r);
		}
	}
	return 0;
}
f0105fe9:	83 c4 3c             	add    $0x3c,%esp
f0105fec:	5b                   	pop    %ebx
f0105fed:	5e                   	pop    %esi
f0105fee:	5f                   	pop    %edi
f0105fef:	5d                   	pop    %ebp
f0105ff0:	c3                   	ret    

f0105ff1 <pci_conf1_set_addr>:
static void
pci_conf1_set_addr(uint32_t bus,
		   uint32_t dev,
		   uint32_t func,
		   uint32_t offset)
{
f0105ff1:	55                   	push   %ebp
f0105ff2:	89 e5                	mov    %esp,%ebp
f0105ff4:	53                   	push   %ebx
f0105ff5:	83 ec 14             	sub    $0x14,%esp
f0105ff8:	8b 5d 08             	mov    0x8(%ebp),%ebx
	assert(bus < 256);
f0105ffb:	3d ff 00 00 00       	cmp    $0xff,%eax
f0106000:	76 24                	jbe    f0106026 <pci_conf1_set_addr+0x35>
f0106002:	c7 44 24 0c 28 83 10 	movl   $0xf0108328,0xc(%esp)
f0106009:	f0 
f010600a:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0106011:	f0 
f0106012:	c7 44 24 04 2c 00 00 	movl   $0x2c,0x4(%esp)
f0106019:	00 
f010601a:	c7 04 24 32 83 10 f0 	movl   $0xf0108332,(%esp)
f0106021:	e8 5f a0 ff ff       	call   f0100085 <_panic>
	assert(dev < 32);
f0106026:	83 fa 1f             	cmp    $0x1f,%edx
f0106029:	76 24                	jbe    f010604f <pci_conf1_set_addr+0x5e>
f010602b:	c7 44 24 0c 3d 83 10 	movl   $0xf010833d,0xc(%esp)
f0106032:	f0 
f0106033:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f010603a:	f0 
f010603b:	c7 44 24 04 2d 00 00 	movl   $0x2d,0x4(%esp)
f0106042:	00 
f0106043:	c7 04 24 32 83 10 f0 	movl   $0xf0108332,(%esp)
f010604a:	e8 36 a0 ff ff       	call   f0100085 <_panic>
	assert(func < 8);
f010604f:	83 f9 07             	cmp    $0x7,%ecx
f0106052:	76 24                	jbe    f0106078 <pci_conf1_set_addr+0x87>
f0106054:	c7 44 24 0c 46 83 10 	movl   $0xf0108346,0xc(%esp)
f010605b:	f0 
f010605c:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f0106063:	f0 
f0106064:	c7 44 24 04 2e 00 00 	movl   $0x2e,0x4(%esp)
f010606b:	00 
f010606c:	c7 04 24 32 83 10 f0 	movl   $0xf0108332,(%esp)
f0106073:	e8 0d a0 ff ff       	call   f0100085 <_panic>
	assert(offset < 256);
f0106078:	81 fb ff 00 00 00    	cmp    $0xff,%ebx
f010607e:	76 24                	jbe    f01060a4 <pci_conf1_set_addr+0xb3>
f0106080:	c7 44 24 0c 4f 83 10 	movl   $0xf010834f,0xc(%esp)
f0106087:	f0 
f0106088:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f010608f:	f0 
f0106090:	c7 44 24 04 2f 00 00 	movl   $0x2f,0x4(%esp)
f0106097:	00 
f0106098:	c7 04 24 32 83 10 f0 	movl   $0xf0108332,(%esp)
f010609f:	e8 e1 9f ff ff       	call   f0100085 <_panic>
	assert((offset & 0x3) == 0);
f01060a4:	f6 c3 03             	test   $0x3,%bl
f01060a7:	74 24                	je     f01060cd <pci_conf1_set_addr+0xdc>
f01060a9:	c7 44 24 0c 5c 83 10 	movl   $0xf010835c,0xc(%esp)
f01060b0:	f0 
f01060b1:	c7 44 24 08 8b 6c 10 	movl   $0xf0106c8b,0x8(%esp)
f01060b8:	f0 
f01060b9:	c7 44 24 04 30 00 00 	movl   $0x30,0x4(%esp)
f01060c0:	00 
f01060c1:	c7 04 24 32 83 10 f0 	movl   $0xf0108332,(%esp)
f01060c8:	e8 b8 9f ff ff       	call   f0100085 <_panic>
}

static __inline void
outl(int port, uint32_t data)
{
	__asm __volatile("outl %0,%w1" : : "a" (data), "d" (port));
f01060cd:	c1 e0 10             	shl    $0x10,%eax
f01060d0:	0d 00 00 00 80       	or     $0x80000000,%eax
f01060d5:	c1 e2 0b             	shl    $0xb,%edx
f01060d8:	09 d0                	or     %edx,%eax
f01060da:	09 d8                	or     %ebx,%eax
f01060dc:	c1 e1 08             	shl    $0x8,%ecx
f01060df:	09 c8                	or     %ecx,%eax
f01060e1:	ba f8 0c 00 00       	mov    $0xcf8,%edx
f01060e6:	ef                   	out    %eax,(%dx)
	
	uint32_t v = (1 << 31) |		// config-space
		(bus << 16) | (dev << 11) | (func << 8) | (offset);
	outl(pci_conf1_addr_ioport, v);
}
f01060e7:	83 c4 14             	add    $0x14,%esp
f01060ea:	5b                   	pop    %ebx
f01060eb:	5d                   	pop    %ebp
f01060ec:	c3                   	ret    

f01060ed <pci_conf_read>:

static uint32_t
pci_conf_read(struct pci_func *f, uint32_t off)
{
f01060ed:	55                   	push   %ebp
f01060ee:	89 e5                	mov    %esp,%ebp
f01060f0:	53                   	push   %ebx
f01060f1:	83 ec 14             	sub    $0x14,%esp
f01060f4:	89 d3                	mov    %edx,%ebx
	pci_conf1_set_addr(f->bus->busno, f->dev, f->func, off);
f01060f6:	8b 48 08             	mov    0x8(%eax),%ecx
f01060f9:	8b 50 04             	mov    0x4(%eax),%edx
f01060fc:	8b 00                	mov    (%eax),%eax
f01060fe:	8b 40 04             	mov    0x4(%eax),%eax
f0106101:	89 1c 24             	mov    %ebx,(%esp)
f0106104:	e8 e8 fe ff ff       	call   f0105ff1 <pci_conf1_set_addr>

static __inline uint32_t
inl(int port)
{
	uint32_t data;
	__asm __volatile("inl %w1,%0" : "=a" (data) : "d" (port));
f0106109:	ba fc 0c 00 00       	mov    $0xcfc,%edx
f010610e:	ed                   	in     (%dx),%eax
	return inl(pci_conf1_data_ioport);
}
f010610f:	83 c4 14             	add    $0x14,%esp
f0106112:	5b                   	pop    %ebx
f0106113:	5d                   	pop    %ebp
f0106114:	c3                   	ret    

f0106115 <pci_scan_bus>:
		f->irq_line);
}

static int 
pci_scan_bus(struct pci_bus *bus)
{
f0106115:	55                   	push   %ebp
f0106116:	89 e5                	mov    %esp,%ebp
f0106118:	57                   	push   %edi
f0106119:	56                   	push   %esi
f010611a:	53                   	push   %ebx
f010611b:	81 ec 3c 01 00 00    	sub    $0x13c,%esp
f0106121:	89 c3                	mov    %eax,%ebx
	int totaldev = 0;
	struct pci_func df;
	memset(&df, 0, sizeof(df));
f0106123:	c7 44 24 08 48 00 00 	movl   $0x48,0x8(%esp)
f010612a:	00 
f010612b:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
f0106132:	00 
f0106133:	8d 45 a0             	lea    -0x60(%ebp),%eax
f0106136:	89 04 24             	mov    %eax,(%esp)
f0106139:	e8 68 f9 ff ff       	call   f0105aa6 <memset>
	df.bus = bus;
f010613e:	89 5d a0             	mov    %ebx,-0x60(%ebp)
	
	for (df.dev = 0; df.dev < 32; df.dev++) {
f0106141:	c7 45 a4 00 00 00 00 	movl   $0x0,-0x5c(%ebp)
};

static void 
pci_print_func(struct pci_func *f)
{
	const char *class = pci_class[0];
f0106148:	c7 85 fc fe ff ff 00 	movl   $0x0,-0x104(%ebp)
f010614f:	00 00 00 
	struct pci_func df;
	memset(&df, 0, sizeof(df));
	df.bus = bus;
	
	for (df.dev = 0; df.dev < 32; df.dev++) {
		uint32_t bhlc = pci_conf_read(&df, PCI_BHLC_REG);
f0106152:	8d 45 a0             	lea    -0x60(%ebp),%eax
f0106155:	89 85 f0 fe ff ff    	mov    %eax,-0x110(%ebp)
		if (PCI_HDRTYPE_TYPE(bhlc) > 1)	    // Unsupported or no device
			continue;
		
		totaldev++;
		
		struct pci_func f = df;
f010615b:	8d 8d 58 ff ff ff    	lea    -0xa8(%ebp),%ecx
f0106161:	89 8d f4 fe ff ff    	mov    %ecx,-0x10c(%ebp)
		for (f.func = 0; f.func < (PCI_HDRTYPE_MULTIFN(bhlc) ? 8 : 1);
		     f.func++) {
			struct pci_func af = f;
f0106167:	8d 85 10 ff ff ff    	lea    -0xf0(%ebp),%eax
f010616d:	89 85 ec fe ff ff    	mov    %eax,-0x114(%ebp)
f0106173:	89 8d 00 ff ff ff    	mov    %ecx,-0x100(%ebp)
f0106179:	89 85 04 ff ff ff    	mov    %eax,-0xfc(%ebp)
	struct pci_func df;
	memset(&df, 0, sizeof(df));
	df.bus = bus;
	
	for (df.dev = 0; df.dev < 32; df.dev++) {
		uint32_t bhlc = pci_conf_read(&df, PCI_BHLC_REG);
f010617f:	ba 0c 00 00 00       	mov    $0xc,%edx
f0106184:	8d 45 a0             	lea    -0x60(%ebp),%eax
f0106187:	e8 61 ff ff ff       	call   f01060ed <pci_conf_read>
		if (PCI_HDRTYPE_TYPE(bhlc) > 1)	    // Unsupported or no device
f010618c:	89 c2                	mov    %eax,%edx
f010618e:	c1 ea 10             	shr    $0x10,%edx
f0106191:	83 e2 7f             	and    $0x7f,%edx
f0106194:	83 fa 01             	cmp    $0x1,%edx
f0106197:	0f 87 77 01 00 00    	ja     f0106314 <pci_scan_bus+0x1ff>
			continue;
		
		totaldev++;
		
		struct pci_func f = df;
f010619d:	b9 12 00 00 00       	mov    $0x12,%ecx
f01061a2:	8b bd f4 fe ff ff    	mov    -0x10c(%ebp),%edi
f01061a8:	8b b5 f0 fe ff ff    	mov    -0x110(%ebp),%esi
f01061ae:	f3 a5                	rep movsl %ds:(%esi),%es:(%edi)
		for (f.func = 0; f.func < (PCI_HDRTYPE_MULTIFN(bhlc) ? 8 : 1);
f01061b0:	c7 85 60 ff ff ff 00 	movl   $0x0,-0xa0(%ebp)
f01061b7:	00 00 00 
f01061ba:	89 c3                	mov    %eax,%ebx
f01061bc:	81 e3 00 00 80 00    	and    $0x800000,%ebx
f01061c2:	e9 2f 01 00 00       	jmp    f01062f6 <pci_scan_bus+0x1e1>
		     f.func++) {
			struct pci_func af = f;
f01061c7:	8b bd ec fe ff ff    	mov    -0x114(%ebp),%edi
f01061cd:	8b b5 f4 fe ff ff    	mov    -0x10c(%ebp),%esi
f01061d3:	b9 12 00 00 00       	mov    $0x12,%ecx
f01061d8:	f3 a5                	rep movsl %ds:(%esi),%es:(%edi)
			
			af.dev_id = pci_conf_read(&f, PCI_ID_REG);
f01061da:	ba 00 00 00 00       	mov    $0x0,%edx
f01061df:	8b 85 00 ff ff ff    	mov    -0x100(%ebp),%eax
f01061e5:	e8 03 ff ff ff       	call   f01060ed <pci_conf_read>
f01061ea:	89 85 1c ff ff ff    	mov    %eax,-0xe4(%ebp)

			if (PCI_VENDOR(af.dev_id) == 0xffff)
f01061f0:	66 83 f8 ff          	cmp    $0xffffffff,%ax
f01061f4:	0f 84 f5 00 00 00    	je     f01062ef <pci_scan_bus+0x1da>
				continue;
			
			uint32_t intr = pci_conf_read(&af, PCI_INTERRUPT_REG);
f01061fa:	ba 3c 00 00 00       	mov    $0x3c,%edx
f01061ff:	8b 85 04 ff ff ff    	mov    -0xfc(%ebp),%eax
f0106205:	e8 e3 fe ff ff       	call   f01060ed <pci_conf_read>
			af.irq_line = PCI_INTERRUPT_LINE(intr);
f010620a:	88 85 54 ff ff ff    	mov    %al,-0xac(%ebp)
			
			af.dev_class = pci_conf_read(&af, PCI_CLASS_REG);
f0106210:	ba 08 00 00 00       	mov    $0x8,%edx
f0106215:	8b 85 04 ff ff ff    	mov    -0xfc(%ebp),%eax
f010621b:	e8 cd fe ff ff       	call   f01060ed <pci_conf_read>
f0106220:	89 85 20 ff ff ff    	mov    %eax,-0xe0(%ebp)

static void 
pci_print_func(struct pci_func *f)
{
	const char *class = pci_class[0];
	if (PCI_CLASS(f->dev_class) < sizeof(pci_class) / sizeof(pci_class[0]))
f0106226:	89 c2                	mov    %eax,%edx
f0106228:	c1 ea 18             	shr    $0x18,%edx
f010622b:	b9 70 83 10 f0       	mov    $0xf0108370,%ecx
f0106230:	83 fa 06             	cmp    $0x6,%edx
f0106233:	77 07                	ja     f010623c <pci_scan_bus+0x127>
		class = pci_class[PCI_CLASS(f->dev_class)];
f0106235:	8b 0c 95 e4 83 10 f0 	mov    -0xfef7c1c(,%edx,4),%ecx

	cprintf("PCI: %02x:%02x.%d: %04x:%04x: class: %x.%x (%s) irq: %d\n",
		f->bus->busno, f->dev, f->func,
		PCI_VENDOR(f->dev_id), PCI_PRODUCT(f->dev_id),
f010623c:	8b bd 1c ff ff ff    	mov    -0xe4(%ebp),%edi
{
	const char *class = pci_class[0];
	if (PCI_CLASS(f->dev_class) < sizeof(pci_class) / sizeof(pci_class[0]))
		class = pci_class[PCI_CLASS(f->dev_class)];

	cprintf("PCI: %02x:%02x.%d: %04x:%04x: class: %x.%x (%s) irq: %d\n",
f0106242:	0f b6 b5 54 ff ff ff 	movzbl -0xac(%ebp),%esi
f0106249:	89 74 24 24          	mov    %esi,0x24(%esp)
f010624d:	89 4c 24 20          	mov    %ecx,0x20(%esp)
f0106251:	c1 e8 10             	shr    $0x10,%eax
f0106254:	25 ff 00 00 00       	and    $0xff,%eax
f0106259:	89 44 24 1c          	mov    %eax,0x1c(%esp)
f010625d:	89 54 24 18          	mov    %edx,0x18(%esp)
f0106261:	89 f8                	mov    %edi,%eax
f0106263:	c1 e8 10             	shr    $0x10,%eax
f0106266:	89 44 24 14          	mov    %eax,0x14(%esp)
f010626a:	81 e7 ff ff 00 00    	and    $0xffff,%edi
f0106270:	89 7c 24 10          	mov    %edi,0x10(%esp)
f0106274:	8b 85 18 ff ff ff    	mov    -0xe8(%ebp),%eax
f010627a:	89 44 24 0c          	mov    %eax,0xc(%esp)
f010627e:	8b 85 14 ff ff ff    	mov    -0xec(%ebp),%eax
f0106284:	89 44 24 08          	mov    %eax,0x8(%esp)
f0106288:	8b 85 10 ff ff ff    	mov    -0xf0(%ebp),%eax
f010628e:	8b 40 04             	mov    0x4(%eax),%eax
f0106291:	89 44 24 04          	mov    %eax,0x4(%esp)
f0106295:	c7 04 24 b4 81 10 f0 	movl   $0xf01081b4,(%esp)
f010629c:	e8 3e d7 ff ff       	call   f01039df <cprintf>
static int
pci_attach(struct pci_func *f)
{
	return
		pci_attach_match(PCI_CLASS(f->dev_class), 
				 PCI_SUBCLASS(f->dev_class),
f01062a1:	8b 85 20 ff ff ff    	mov    -0xe0(%ebp),%eax
				 &pci_attach_class[0], f) ||
f01062a7:	89 c2                	mov    %eax,%edx
f01062a9:	c1 ea 10             	shr    $0x10,%edx
f01062ac:	81 e2 ff 00 00 00    	and    $0xff,%edx
f01062b2:	c1 e8 18             	shr    $0x18,%eax
f01062b5:	8b 8d 04 ff ff ff    	mov    -0xfc(%ebp),%ecx
f01062bb:	89 0c 24             	mov    %ecx,(%esp)
f01062be:	b9 c4 e3 11 f0       	mov    $0xf011e3c4,%ecx
f01062c3:	e8 b8 fc ff ff       	call   f0105f80 <pci_attach_match>

static int
pci_attach(struct pci_func *f)
{
	return
		pci_attach_match(PCI_CLASS(f->dev_class), 
f01062c8:	85 c0                	test   %eax,%eax
f01062ca:	75 23                	jne    f01062ef <pci_scan_bus+0x1da>
				 PCI_SUBCLASS(f->dev_class),
				 &pci_attach_class[0], f) ||
		pci_attach_match(PCI_VENDOR(f->dev_id), 
				 PCI_PRODUCT(f->dev_id),
f01062cc:	8b 85 1c ff ff ff    	mov    -0xe4(%ebp),%eax
				 &pci_attach_vendor[0], f);
f01062d2:	89 c2                	mov    %eax,%edx
f01062d4:	c1 ea 10             	shr    $0x10,%edx
f01062d7:	25 ff ff 00 00       	and    $0xffff,%eax
f01062dc:	8b 8d 04 ff ff ff    	mov    -0xfc(%ebp),%ecx
f01062e2:	89 0c 24             	mov    %ecx,(%esp)
f01062e5:	b9 dc e3 11 f0       	mov    $0xf011e3dc,%ecx
f01062ea:	e8 91 fc ff ff       	call   f0105f80 <pci_attach_match>
		
		totaldev++;
		
		struct pci_func f = df;
		for (f.func = 0; f.func < (PCI_HDRTYPE_MULTIFN(bhlc) ? 8 : 1);
		     f.func++) {
f01062ef:	83 85 60 ff ff ff 01 	addl   $0x1,-0xa0(%ebp)
			continue;
		
		totaldev++;
		
		struct pci_func f = df;
		for (f.func = 0; f.func < (PCI_HDRTYPE_MULTIFN(bhlc) ? 8 : 1);
f01062f6:	83 fb 01             	cmp    $0x1,%ebx
f01062f9:	19 c0                	sbb    %eax,%eax
f01062fb:	83 e0 f9             	and    $0xfffffff9,%eax
f01062fe:	83 c0 08             	add    $0x8,%eax
f0106301:	3b 85 60 ff ff ff    	cmp    -0xa0(%ebp),%eax
f0106307:	0f 87 ba fe ff ff    	ja     f01061c7 <pci_scan_bus+0xb2>
	for (df.dev = 0; df.dev < 32; df.dev++) {
		uint32_t bhlc = pci_conf_read(&df, PCI_BHLC_REG);
		if (PCI_HDRTYPE_TYPE(bhlc) > 1)	    // Unsupported or no device
			continue;
		
		totaldev++;
f010630d:	83 85 fc fe ff ff 01 	addl   $0x1,-0x104(%ebp)
	int totaldev = 0;
	struct pci_func df;
	memset(&df, 0, sizeof(df));
	df.bus = bus;
	
	for (df.dev = 0; df.dev < 32; df.dev++) {
f0106314:	8b 45 a4             	mov    -0x5c(%ebp),%eax
f0106317:	83 c0 01             	add    $0x1,%eax
f010631a:	89 45 a4             	mov    %eax,-0x5c(%ebp)
f010631d:	83 f8 1f             	cmp    $0x1f,%eax
f0106320:	0f 86 59 fe ff ff    	jbe    f010617f <pci_scan_bus+0x6a>
			pci_attach(&af);
		}
	}
	
	return totaldev;
}
f0106326:	8b 85 fc fe ff ff    	mov    -0x104(%ebp),%eax
f010632c:	81 c4 3c 01 00 00    	add    $0x13c,%esp
f0106332:	5b                   	pop    %ebx
f0106333:	5e                   	pop    %esi
f0106334:	5f                   	pop    %edi
f0106335:	5d                   	pop    %ebp
f0106336:	c3                   	ret    

f0106337 <pci_init>:
		PCI_VENDOR(f->dev_id), PCI_PRODUCT(f->dev_id));
}

int
pci_init(void)
{
f0106337:	55                   	push   %ebp
f0106338:	89 e5                	mov    %esp,%ebp
f010633a:	83 ec 18             	sub    $0x18,%esp
	static struct pci_bus root_bus;
	memset(&root_bus, 0, sizeof(root_bus));
f010633d:	c7 44 24 08 08 00 00 	movl   $0x8,0x8(%esp)
f0106344:	00 
f0106345:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
f010634c:	00 
f010634d:	c7 04 24 00 ff 2c f0 	movl   $0xf02cff00,(%esp)
f0106354:	e8 4d f7 ff ff       	call   f0105aa6 <memset>
	
	return pci_scan_bus(&root_bus);
f0106359:	b8 00 ff 2c f0       	mov    $0xf02cff00,%eax
f010635e:	e8 b2 fd ff ff       	call   f0106115 <pci_scan_bus>
}
f0106363:	c9                   	leave  
f0106364:	c3                   	ret    

f0106365 <pci_bridge_attach>:
	return 1;
}

static int
pci_bridge_attach(struct pci_func *pcif)
{
f0106365:	55                   	push   %ebp
f0106366:	89 e5                	mov    %esp,%ebp
f0106368:	83 ec 48             	sub    $0x48,%esp
f010636b:	89 5d f4             	mov    %ebx,-0xc(%ebp)
f010636e:	89 75 f8             	mov    %esi,-0x8(%ebp)
f0106371:	89 7d fc             	mov    %edi,-0x4(%ebp)
f0106374:	8b 5d 08             	mov    0x8(%ebp),%ebx
	uint32_t ioreg  = pci_conf_read(pcif, PCI_BRIDGE_STATIO_REG);
f0106377:	ba 1c 00 00 00       	mov    $0x1c,%edx
f010637c:	89 d8                	mov    %ebx,%eax
f010637e:	e8 6a fd ff ff       	call   f01060ed <pci_conf_read>
f0106383:	89 c7                	mov    %eax,%edi
	uint32_t busreg = pci_conf_read(pcif, PCI_BRIDGE_BUS_REG);
f0106385:	ba 18 00 00 00       	mov    $0x18,%edx
f010638a:	89 d8                	mov    %ebx,%eax
f010638c:	e8 5c fd ff ff       	call   f01060ed <pci_conf_read>
f0106391:	89 c6                	mov    %eax,%esi
	
	if (PCI_BRIDGE_IO_32BITS(ioreg)) {
f0106393:	83 e7 0f             	and    $0xf,%edi
f0106396:	83 ff 01             	cmp    $0x1,%edi
f0106399:	75 2a                	jne    f01063c5 <pci_bridge_attach+0x60>
		cprintf("PCI: %02x:%02x.%d: 32-bit bridge IO not supported.\n",
f010639b:	8b 43 08             	mov    0x8(%ebx),%eax
f010639e:	89 44 24 0c          	mov    %eax,0xc(%esp)
f01063a2:	8b 43 04             	mov    0x4(%ebx),%eax
f01063a5:	89 44 24 08          	mov    %eax,0x8(%esp)
f01063a9:	8b 03                	mov    (%ebx),%eax
f01063ab:	8b 40 04             	mov    0x4(%eax),%eax
f01063ae:	89 44 24 04          	mov    %eax,0x4(%esp)
f01063b2:	c7 04 24 f0 81 10 f0 	movl   $0xf01081f0,(%esp)
f01063b9:	e8 21 d6 ff ff       	call   f01039df <cprintf>
f01063be:	b8 00 00 00 00       	mov    $0x0,%eax
			pcif->bus->busno, pcif->dev, pcif->func);
		return 0;
f01063c3:	eb 66                	jmp    f010642b <pci_bridge_attach+0xc6>
	}
	
	struct pci_bus nbus;
	memset(&nbus, 0, sizeof(nbus));
f01063c5:	c7 44 24 08 08 00 00 	movl   $0x8,0x8(%esp)
f01063cc:	00 
f01063cd:	c7 44 24 04 00 00 00 	movl   $0x0,0x4(%esp)
f01063d4:	00 
f01063d5:	8d 7d e0             	lea    -0x20(%ebp),%edi
f01063d8:	89 3c 24             	mov    %edi,(%esp)
f01063db:	e8 c6 f6 ff ff       	call   f0105aa6 <memset>
	nbus.parent_bridge = pcif;
f01063e0:	89 5d e0             	mov    %ebx,-0x20(%ebp)
	nbus.busno = (busreg >> PCI_BRIDGE_BUS_SECONDARY_SHIFT) & 0xff;
f01063e3:	89 f2                	mov    %esi,%edx
f01063e5:	0f b6 c6             	movzbl %dh,%eax
f01063e8:	89 45 e4             	mov    %eax,-0x1c(%ebp)
	
	if (pci_show_devs)
		cprintf("PCI: %02x:%02x.%d: bridge to PCI bus %d--%d\n",
f01063eb:	c1 ee 10             	shr    $0x10,%esi
f01063ee:	81 e6 ff 00 00 00    	and    $0xff,%esi
f01063f4:	89 74 24 14          	mov    %esi,0x14(%esp)
f01063f8:	89 44 24 10          	mov    %eax,0x10(%esp)
f01063fc:	8b 43 08             	mov    0x8(%ebx),%eax
f01063ff:	89 44 24 0c          	mov    %eax,0xc(%esp)
f0106403:	8b 43 04             	mov    0x4(%ebx),%eax
f0106406:	89 44 24 08          	mov    %eax,0x8(%esp)
f010640a:	8b 03                	mov    (%ebx),%eax
f010640c:	8b 40 04             	mov    0x4(%eax),%eax
f010640f:	89 44 24 04          	mov    %eax,0x4(%esp)
f0106413:	c7 04 24 24 82 10 f0 	movl   $0xf0108224,(%esp)
f010641a:	e8 c0 d5 ff ff       	call   f01039df <cprintf>
			pcif->bus->busno, pcif->dev, pcif->func,
			nbus.busno,
			(busreg >> PCI_BRIDGE_BUS_SUBORDINATE_SHIFT) & 0xff);
	
	pci_scan_bus(&nbus);
f010641f:	89 f8                	mov    %edi,%eax
f0106421:	e8 ef fc ff ff       	call   f0106115 <pci_scan_bus>
f0106426:	b8 01 00 00 00       	mov    $0x1,%eax
	return 1;
}
f010642b:	8b 5d f4             	mov    -0xc(%ebp),%ebx
f010642e:	8b 75 f8             	mov    -0x8(%ebp),%esi
f0106431:	8b 7d fc             	mov    -0x4(%ebp),%edi
f0106434:	89 ec                	mov    %ebp,%esp
f0106436:	5d                   	pop    %ebp
f0106437:	c3                   	ret    

f0106438 <pci_conf_write>:
	return inl(pci_conf1_data_ioport);
}

static void
pci_conf_write(struct pci_func *f, uint32_t off, uint32_t v)
{
f0106438:	55                   	push   %ebp
f0106439:	89 e5                	mov    %esp,%ebp
f010643b:	83 ec 18             	sub    $0x18,%esp
f010643e:	89 5d f8             	mov    %ebx,-0x8(%ebp)
f0106441:	89 75 fc             	mov    %esi,-0x4(%ebp)
f0106444:	89 d3                	mov    %edx,%ebx
f0106446:	89 ce                	mov    %ecx,%esi
	pci_conf1_set_addr(f->bus->busno, f->dev, f->func, off);
f0106448:	8b 48 08             	mov    0x8(%eax),%ecx
f010644b:	8b 50 04             	mov    0x4(%eax),%edx
f010644e:	8b 00                	mov    (%eax),%eax
f0106450:	8b 40 04             	mov    0x4(%eax),%eax
f0106453:	89 1c 24             	mov    %ebx,(%esp)
f0106456:	e8 96 fb ff ff       	call   f0105ff1 <pci_conf1_set_addr>
}

static __inline void
outl(int port, uint32_t data)
{
	__asm __volatile("outl %0,%w1" : : "a" (data), "d" (port));
f010645b:	ba fc 0c 00 00       	mov    $0xcfc,%edx
f0106460:	89 f0                	mov    %esi,%eax
f0106462:	ef                   	out    %eax,(%dx)
	outl(pci_conf1_data_ioport, v);
}
f0106463:	8b 5d f8             	mov    -0x8(%ebp),%ebx
f0106466:	8b 75 fc             	mov    -0x4(%ebp),%esi
f0106469:	89 ec                	mov    %ebp,%esp
f010646b:	5d                   	pop    %ebp
f010646c:	c3                   	ret    

f010646d <pci_func_enable>:

// External PCI subsystem interface

void
pci_func_enable(struct pci_func *f)
{
f010646d:	55                   	push   %ebp
f010646e:	89 e5                	mov    %esp,%ebp
f0106470:	57                   	push   %edi
f0106471:	56                   	push   %esi
f0106472:	53                   	push   %ebx
f0106473:	83 ec 4c             	sub    $0x4c,%esp
f0106476:	8b 5d 08             	mov    0x8(%ebp),%ebx
	pci_conf_write(f, PCI_COMMAND_STATUS_REG,
f0106479:	b9 07 00 00 00       	mov    $0x7,%ecx
f010647e:	ba 04 00 00 00       	mov    $0x4,%edx
f0106483:	89 d8                	mov    %ebx,%eax
f0106485:	e8 ae ff ff ff       	call   f0106438 <pci_conf_write>
f010648a:	be 10 00 00 00       	mov    $0x10,%esi
	uint32_t bar_width;
	uint32_t bar;
	for (bar = PCI_MAPREG_START; bar < PCI_MAPREG_END;
	     bar += bar_width)
	{
		uint32_t oldv = pci_conf_read(f, bar);
f010648f:	89 f2                	mov    %esi,%edx
f0106491:	89 d8                	mov    %ebx,%eax
f0106493:	e8 55 fc ff ff       	call   f01060ed <pci_conf_read>
f0106498:	89 45 dc             	mov    %eax,-0x24(%ebp)
		
		bar_width = 4;
		pci_conf_write(f, bar, 0xffffffff);
f010649b:	b9 ff ff ff ff       	mov    $0xffffffff,%ecx
f01064a0:	89 f2                	mov    %esi,%edx
f01064a2:	89 d8                	mov    %ebx,%eax
f01064a4:	e8 8f ff ff ff       	call   f0106438 <pci_conf_write>
		uint32_t rv = pci_conf_read(f, bar);
f01064a9:	89 f2                	mov    %esi,%edx
f01064ab:	89 d8                	mov    %ebx,%eax
f01064ad:	e8 3b fc ff ff       	call   f01060ed <pci_conf_read>
		
		if (rv == 0)
f01064b2:	bf 04 00 00 00       	mov    $0x4,%edi
f01064b7:	85 c0                	test   %eax,%eax
f01064b9:	0f 84 fa 00 00 00    	je     f01065b9 <pci_func_enable+0x14c>
			continue;
		
		int regnum = PCI_MAPREG_NUM(bar);
f01064bf:	8d 56 f0             	lea    -0x10(%esi),%edx
f01064c2:	c1 ea 02             	shr    $0x2,%edx
f01064c5:	89 55 e4             	mov    %edx,-0x1c(%ebp)
		uint32_t base, size;
		if (PCI_MAPREG_TYPE(rv) == PCI_MAPREG_TYPE_MEM) {
f01064c8:	a8 01                	test   $0x1,%al
f01064ca:	75 47                	jne    f0106513 <pci_func_enable+0xa6>
			if (PCI_MAPREG_MEM_TYPE(rv) == PCI_MAPREG_MEM_TYPE_64BIT)
f01064cc:	89 c2                	mov    %eax,%edx
f01064ce:	83 e2 06             	and    $0x6,%edx
f01064d1:	83 fa 04             	cmp    $0x4,%edx
f01064d4:	0f 94 c2             	sete   %dl
f01064d7:	0f b6 fa             	movzbl %dl,%edi
f01064da:	8d 3c bd 04 00 00 00 	lea    0x4(,%edi,4),%edi
				bar_width = 8;
			
			size = PCI_MAPREG_MEM_SIZE(rv);
f01064e1:	83 e0 f0             	and    $0xfffffff0,%eax
f01064e4:	89 c2                	mov    %eax,%edx
f01064e6:	f7 da                	neg    %edx
f01064e8:	21 c2                	and    %eax,%edx
f01064ea:	89 55 e0             	mov    %edx,-0x20(%ebp)
			base = PCI_MAPREG_MEM_ADDR(oldv);
f01064ed:	8b 45 dc             	mov    -0x24(%ebp),%eax
f01064f0:	83 e0 f0             	and    $0xfffffff0,%eax
f01064f3:	89 45 d8             	mov    %eax,-0x28(%ebp)
			if (pci_show_addrs)
				cprintf("  mem region %d: %d bytes at 0x%x\n",
f01064f6:	89 44 24 0c          	mov    %eax,0xc(%esp)
f01064fa:	89 54 24 08          	mov    %edx,0x8(%esp)
f01064fe:	8b 55 e4             	mov    -0x1c(%ebp),%edx
f0106501:	89 54 24 04          	mov    %edx,0x4(%esp)
f0106505:	c7 04 24 54 82 10 f0 	movl   $0xf0108254,(%esp)
f010650c:	e8 ce d4 ff ff       	call   f01039df <cprintf>
f0106511:	eb 35                	jmp    f0106548 <pci_func_enable+0xdb>
					regnum, size, base);
		} else {
			size = PCI_MAPREG_IO_SIZE(rv);
f0106513:	83 e0 fc             	and    $0xfffffffc,%eax
f0106516:	89 c2                	mov    %eax,%edx
f0106518:	f7 da                	neg    %edx
f010651a:	21 c2                	and    %eax,%edx
f010651c:	89 55 e0             	mov    %edx,-0x20(%ebp)
			base = PCI_MAPREG_IO_ADDR(oldv);
f010651f:	8b 45 dc             	mov    -0x24(%ebp),%eax
f0106522:	83 e0 fc             	and    $0xfffffffc,%eax
f0106525:	89 45 d8             	mov    %eax,-0x28(%ebp)
			if (pci_show_addrs)
				cprintf("  io region %d: %d bytes at 0x%x\n",
f0106528:	89 44 24 0c          	mov    %eax,0xc(%esp)
f010652c:	89 54 24 08          	mov    %edx,0x8(%esp)
f0106530:	8b 55 e4             	mov    -0x1c(%ebp),%edx
f0106533:	89 54 24 04          	mov    %edx,0x4(%esp)
f0106537:	c7 04 24 78 82 10 f0 	movl   $0xf0108278,(%esp)
f010653e:	e8 9c d4 ff ff       	call   f01039df <cprintf>
f0106543:	bf 04 00 00 00       	mov    $0x4,%edi
					regnum, size, base);
		}
		
		pci_conf_write(f, bar, oldv);
f0106548:	8b 4d dc             	mov    -0x24(%ebp),%ecx
f010654b:	89 f2                	mov    %esi,%edx
f010654d:	89 d8                	mov    %ebx,%eax
f010654f:	e8 e4 fe ff ff       	call   f0106438 <pci_conf_write>
		f->reg_base[regnum] = base;
f0106554:	8b 55 d8             	mov    -0x28(%ebp),%edx
f0106557:	8b 45 e4             	mov    -0x1c(%ebp),%eax
f010655a:	89 54 83 14          	mov    %edx,0x14(%ebx,%eax,4)
		f->reg_size[regnum] = size;
f010655e:	8b 55 e0             	mov    -0x20(%ebp),%edx
f0106561:	89 54 83 2c          	mov    %edx,0x2c(%ebx,%eax,4)
		
		if (size && !base)
f0106565:	85 d2                	test   %edx,%edx
f0106567:	74 50                	je     f01065b9 <pci_func_enable+0x14c>
f0106569:	83 7d d8 00          	cmpl   $0x0,-0x28(%ebp)
f010656d:	75 4a                	jne    f01065b9 <pci_func_enable+0x14c>
			cprintf("PCI device %02x:%02x.%d (%04x:%04x) "
				"may be misconfigured: "
				"region %d: base 0x%x, size %d\n",
				f->bus->busno, f->dev, f->func,
				PCI_VENDOR(f->dev_id), PCI_PRODUCT(f->dev_id),
f010656f:	8b 43 0c             	mov    0xc(%ebx),%eax
		pci_conf_write(f, bar, oldv);
		f->reg_base[regnum] = base;
		f->reg_size[regnum] = size;
		
		if (size && !base)
			cprintf("PCI device %02x:%02x.%d (%04x:%04x) "
f0106572:	89 54 24 20          	mov    %edx,0x20(%esp)
f0106576:	8b 55 d8             	mov    -0x28(%ebp),%edx
f0106579:	89 54 24 1c          	mov    %edx,0x1c(%esp)
f010657d:	8b 55 e4             	mov    -0x1c(%ebp),%edx
f0106580:	89 54 24 18          	mov    %edx,0x18(%esp)
f0106584:	89 c2                	mov    %eax,%edx
f0106586:	c1 ea 10             	shr    $0x10,%edx
f0106589:	89 54 24 14          	mov    %edx,0x14(%esp)
f010658d:	25 ff ff 00 00       	and    $0xffff,%eax
f0106592:	89 44 24 10          	mov    %eax,0x10(%esp)
f0106596:	8b 43 08             	mov    0x8(%ebx),%eax
f0106599:	89 44 24 0c          	mov    %eax,0xc(%esp)
f010659d:	8b 43 04             	mov    0x4(%ebx),%eax
f01065a0:	89 44 24 08          	mov    %eax,0x8(%esp)
f01065a4:	8b 03                	mov    (%ebx),%eax
f01065a6:	8b 40 04             	mov    0x4(%eax),%eax
f01065a9:	89 44 24 04          	mov    %eax,0x4(%esp)
f01065ad:	c7 04 24 9c 82 10 f0 	movl   $0xf010829c,(%esp)
f01065b4:	e8 26 d4 ff ff       	call   f01039df <cprintf>
		       PCI_COMMAND_MASTER_ENABLE);
	
	uint32_t bar_width;
	uint32_t bar;
	for (bar = PCI_MAPREG_START; bar < PCI_MAPREG_END;
	     bar += bar_width)
f01065b9:	01 fe                	add    %edi,%esi
		       PCI_COMMAND_MEM_ENABLE |
		       PCI_COMMAND_MASTER_ENABLE);
	
	uint32_t bar_width;
	uint32_t bar;
	for (bar = PCI_MAPREG_START; bar < PCI_MAPREG_END;
f01065bb:	83 fe 27             	cmp    $0x27,%esi
f01065be:	0f 86 cb fe ff ff    	jbe    f010648f <pci_func_enable+0x22>
				regnum, base, size);
	}

	cprintf("PCI function %02x:%02x.%d (%04x:%04x) enabled\n",
		f->bus->busno, f->dev, f->func,
		PCI_VENDOR(f->dev_id), PCI_PRODUCT(f->dev_id));
f01065c4:	8b 43 0c             	mov    0xc(%ebx),%eax
				f->bus->busno, f->dev, f->func,
				PCI_VENDOR(f->dev_id), PCI_PRODUCT(f->dev_id),
				regnum, base, size);
	}

	cprintf("PCI function %02x:%02x.%d (%04x:%04x) enabled\n",
f01065c7:	89 c2                	mov    %eax,%edx
f01065c9:	c1 ea 10             	shr    $0x10,%edx
f01065cc:	89 54 24 14          	mov    %edx,0x14(%esp)
f01065d0:	25 ff ff 00 00       	and    $0xffff,%eax
f01065d5:	89 44 24 10          	mov    %eax,0x10(%esp)
f01065d9:	8b 43 08             	mov    0x8(%ebx),%eax
f01065dc:	89 44 24 0c          	mov    %eax,0xc(%esp)
f01065e0:	8b 43 04             	mov    0x4(%ebx),%eax
f01065e3:	89 44 24 08          	mov    %eax,0x8(%esp)
f01065e7:	8b 03                	mov    (%ebx),%eax
f01065e9:	8b 40 04             	mov    0x4(%eax),%eax
f01065ec:	89 44 24 04          	mov    %eax,0x4(%esp)
f01065f0:	c7 04 24 f8 82 10 f0 	movl   $0xf01082f8,(%esp)
f01065f7:	e8 e3 d3 ff ff       	call   f01039df <cprintf>
		f->bus->busno, f->dev, f->func,
		PCI_VENDOR(f->dev_id), PCI_PRODUCT(f->dev_id));
}
f01065fc:	83 c4 4c             	add    $0x4c,%esp
f01065ff:	5b                   	pop    %ebx
f0106600:	5e                   	pop    %esi
f0106601:	5f                   	pop    %edi
f0106602:	5d                   	pop    %ebp
f0106603:	c3                   	ret    

f0106604 <pci_vendor_attach>:
	
	return totaldev;
}

static int
pci_vendor_attach(struct pci_func *pcif) {
f0106604:	55                   	push   %ebp
f0106605:	89 e5                	mov    %esp,%ebp
f0106607:	83 ec 28             	sub    $0x28,%esp
f010660a:	89 5d f4             	mov    %ebx,-0xc(%ebp)
f010660d:	89 75 f8             	mov    %esi,-0x8(%ebp)
f0106610:	89 7d fc             	mov    %edi,-0x4(%ebp)
f0106613:	8b 5d 08             	mov    0x8(%ebp),%ebx
    pci_func_enable(pcif);
f0106616:	89 1c 24             	mov    %ebx,(%esp)
f0106619:	e8 4f fe ff ff       	call   f010646d <pci_func_enable>
    // Save network driver function.
    nd  =*pcif;
f010661e:	bf 00 00 2d f0       	mov    $0xf02d0000,%edi
f0106623:	b9 12 00 00 00       	mov    $0x12,%ecx
f0106628:	89 de                	mov    %ebx,%esi
f010662a:	f3 a5                	rep movsl %ds:(%esi),%es:(%edi)
    // Get IO register address from PCI.
    e100_reset_device(pcif->reg_base[1]);//PCI_MAPREG_IO_ADDR(pci_conf_read(pcif, 0x14)));
f010662c:	8b 43 18             	mov    0x18(%ebx),%eax
f010662f:	89 04 24             	mov    %eax,(%esp)
f0106632:	e8 d5 f6 ff ff       	call   f0105d0c <e100_reset_device>
    // Initialize TX DMA Ring.
    e100_init_tx_ring();
f0106637:	e8 a2 f8 ff ff       	call   f0105ede <e100_init_tx_ring>
    // Initialize TX DMA Ring.
    e100_init_rx_ring();
f010663c:	e8 05 f8 ff ff       	call   f0105e46 <e100_init_rx_ring>
	return 1;
}
f0106641:	b8 01 00 00 00       	mov    $0x1,%eax
f0106646:	8b 5d f4             	mov    -0xc(%ebp),%ebx
f0106649:	8b 75 f8             	mov    -0x8(%ebp),%esi
f010664c:	8b 7d fc             	mov    -0x4(%ebp),%edi
f010664f:	89 ec                	mov    %ebp,%esp
f0106651:	5d                   	pop    %ebp
f0106652:	c3                   	ret    
	...

f0106654 <time_init>:

static unsigned int ticks;

void
time_init(void) 
{
f0106654:	55                   	push   %ebp
f0106655:	89 e5                	mov    %esp,%ebp
	ticks = 0;
f0106657:	c7 05 08 ff 2c f0 00 	movl   $0x0,0xf02cff08
f010665e:	00 00 00 
}
f0106661:	5d                   	pop    %ebp
f0106662:	c3                   	ret    

f0106663 <time_msec>:
		panic("time_tick: time overflowed");
}

unsigned int
time_msec(void) 
{
f0106663:	55                   	push   %ebp
f0106664:	89 e5                	mov    %esp,%ebp
f0106666:	a1 08 ff 2c f0       	mov    0xf02cff08,%eax
f010666b:	8d 04 80             	lea    (%eax,%eax,4),%eax
f010666e:	01 c0                	add    %eax,%eax
	return ticks * 10;
}
f0106670:	5d                   	pop    %ebp
f0106671:	c3                   	ret    

f0106672 <time_tick>:

// This should be called once per timer interrupt.  A timer interrupt
// fires every 10 ms.
void
time_tick(void) 
{
f0106672:	55                   	push   %ebp
f0106673:	89 e5                	mov    %esp,%ebp
f0106675:	83 ec 18             	sub    $0x18,%esp
	ticks++;
f0106678:	a1 08 ff 2c f0       	mov    0xf02cff08,%eax
f010667d:	83 c0 01             	add    $0x1,%eax
f0106680:	a3 08 ff 2c f0       	mov    %eax,0xf02cff08
	if (ticks * 10 < ticks)
f0106685:	8d 14 80             	lea    (%eax,%eax,4),%edx
f0106688:	01 d2                	add    %edx,%edx
f010668a:	39 d0                	cmp    %edx,%eax
f010668c:	76 1c                	jbe    f01066aa <time_tick+0x38>
		panic("time_tick: time overflowed");
f010668e:	c7 44 24 08 00 84 10 	movl   $0xf0108400,0x8(%esp)
f0106695:	f0 
f0106696:	c7 44 24 04 13 00 00 	movl   $0x13,0x4(%esp)
f010669d:	00 
f010669e:	c7 04 24 1b 84 10 f0 	movl   $0xf010841b,(%esp)
f01066a5:	e8 db 99 ff ff       	call   f0100085 <_panic>
}
f01066aa:	c9                   	leave  
f01066ab:	c3                   	ret    
f01066ac:	00 00                	add    %al,(%eax)
	...

f01066b0 <__udivdi3>:
f01066b0:	55                   	push   %ebp
f01066b1:	89 e5                	mov    %esp,%ebp
f01066b3:	57                   	push   %edi
f01066b4:	56                   	push   %esi
f01066b5:	83 ec 10             	sub    $0x10,%esp
f01066b8:	8b 45 14             	mov    0x14(%ebp),%eax
f01066bb:	8b 55 08             	mov    0x8(%ebp),%edx
f01066be:	8b 75 10             	mov    0x10(%ebp),%esi
f01066c1:	8b 7d 0c             	mov    0xc(%ebp),%edi
f01066c4:	85 c0                	test   %eax,%eax
f01066c6:	89 55 f0             	mov    %edx,-0x10(%ebp)
f01066c9:	75 35                	jne    f0106700 <__udivdi3+0x50>
f01066cb:	39 fe                	cmp    %edi,%esi
f01066cd:	77 61                	ja     f0106730 <__udivdi3+0x80>
f01066cf:	85 f6                	test   %esi,%esi
f01066d1:	75 0b                	jne    f01066de <__udivdi3+0x2e>
f01066d3:	b8 01 00 00 00       	mov    $0x1,%eax
f01066d8:	31 d2                	xor    %edx,%edx
f01066da:	f7 f6                	div    %esi
f01066dc:	89 c6                	mov    %eax,%esi
f01066de:	8b 4d f0             	mov    -0x10(%ebp),%ecx
f01066e1:	31 d2                	xor    %edx,%edx
f01066e3:	89 f8                	mov    %edi,%eax
f01066e5:	f7 f6                	div    %esi
f01066e7:	89 c7                	mov    %eax,%edi
f01066e9:	89 c8                	mov    %ecx,%eax
f01066eb:	f7 f6                	div    %esi
f01066ed:	89 c1                	mov    %eax,%ecx
f01066ef:	89 fa                	mov    %edi,%edx
f01066f1:	89 c8                	mov    %ecx,%eax
f01066f3:	83 c4 10             	add    $0x10,%esp
f01066f6:	5e                   	pop    %esi
f01066f7:	5f                   	pop    %edi
f01066f8:	5d                   	pop    %ebp
f01066f9:	c3                   	ret    
f01066fa:	8d b6 00 00 00 00    	lea    0x0(%esi),%esi
f0106700:	39 f8                	cmp    %edi,%eax
f0106702:	77 1c                	ja     f0106720 <__udivdi3+0x70>
f0106704:	0f bd d0             	bsr    %eax,%edx
f0106707:	83 f2 1f             	xor    $0x1f,%edx
f010670a:	89 55 f4             	mov    %edx,-0xc(%ebp)
f010670d:	75 39                	jne    f0106748 <__udivdi3+0x98>
f010670f:	3b 75 f0             	cmp    -0x10(%ebp),%esi
f0106712:	0f 86 a0 00 00 00    	jbe    f01067b8 <__udivdi3+0x108>
f0106718:	39 f8                	cmp    %edi,%eax
f010671a:	0f 82 98 00 00 00    	jb     f01067b8 <__udivdi3+0x108>
f0106720:	31 ff                	xor    %edi,%edi
f0106722:	31 c9                	xor    %ecx,%ecx
f0106724:	89 c8                	mov    %ecx,%eax
f0106726:	89 fa                	mov    %edi,%edx
f0106728:	83 c4 10             	add    $0x10,%esp
f010672b:	5e                   	pop    %esi
f010672c:	5f                   	pop    %edi
f010672d:	5d                   	pop    %ebp
f010672e:	c3                   	ret    
f010672f:	90                   	nop
f0106730:	89 d1                	mov    %edx,%ecx
f0106732:	89 fa                	mov    %edi,%edx
f0106734:	89 c8                	mov    %ecx,%eax
f0106736:	31 ff                	xor    %edi,%edi
f0106738:	f7 f6                	div    %esi
f010673a:	89 c1                	mov    %eax,%ecx
f010673c:	89 fa                	mov    %edi,%edx
f010673e:	89 c8                	mov    %ecx,%eax
f0106740:	83 c4 10             	add    $0x10,%esp
f0106743:	5e                   	pop    %esi
f0106744:	5f                   	pop    %edi
f0106745:	5d                   	pop    %ebp
f0106746:	c3                   	ret    
f0106747:	90                   	nop
f0106748:	0f b6 4d f4          	movzbl -0xc(%ebp),%ecx
f010674c:	89 f2                	mov    %esi,%edx
f010674e:	d3 e0                	shl    %cl,%eax
f0106750:	89 45 ec             	mov    %eax,-0x14(%ebp)
f0106753:	b8 20 00 00 00       	mov    $0x20,%eax
f0106758:	2b 45 f4             	sub    -0xc(%ebp),%eax
f010675b:	89 c1                	mov    %eax,%ecx
f010675d:	d3 ea                	shr    %cl,%edx
f010675f:	0f b6 4d f4          	movzbl -0xc(%ebp),%ecx
f0106763:	0b 55 ec             	or     -0x14(%ebp),%edx
f0106766:	d3 e6                	shl    %cl,%esi
f0106768:	89 c1                	mov    %eax,%ecx
f010676a:	89 75 e8             	mov    %esi,-0x18(%ebp)
f010676d:	89 fe                	mov    %edi,%esi
f010676f:	d3 ee                	shr    %cl,%esi
f0106771:	0f b6 4d f4          	movzbl -0xc(%ebp),%ecx
f0106775:	89 55 ec             	mov    %edx,-0x14(%ebp)
f0106778:	8b 55 f0             	mov    -0x10(%ebp),%edx
f010677b:	d3 e7                	shl    %cl,%edi
f010677d:	89 c1                	mov    %eax,%ecx
f010677f:	d3 ea                	shr    %cl,%edx
f0106781:	09 d7                	or     %edx,%edi
f0106783:	89 f2                	mov    %esi,%edx
f0106785:	89 f8                	mov    %edi,%eax
f0106787:	f7 75 ec             	divl   -0x14(%ebp)
f010678a:	89 d6                	mov    %edx,%esi
f010678c:	89 c7                	mov    %eax,%edi
f010678e:	f7 65 e8             	mull   -0x18(%ebp)
f0106791:	39 d6                	cmp    %edx,%esi
f0106793:	89 55 ec             	mov    %edx,-0x14(%ebp)
f0106796:	72 30                	jb     f01067c8 <__udivdi3+0x118>
f0106798:	8b 55 f0             	mov    -0x10(%ebp),%edx
f010679b:	0f b6 4d f4          	movzbl -0xc(%ebp),%ecx
f010679f:	d3 e2                	shl    %cl,%edx
f01067a1:	39 c2                	cmp    %eax,%edx
f01067a3:	73 05                	jae    f01067aa <__udivdi3+0xfa>
f01067a5:	3b 75 ec             	cmp    -0x14(%ebp),%esi
f01067a8:	74 1e                	je     f01067c8 <__udivdi3+0x118>
f01067aa:	89 f9                	mov    %edi,%ecx
f01067ac:	31 ff                	xor    %edi,%edi
f01067ae:	e9 71 ff ff ff       	jmp    f0106724 <__udivdi3+0x74>
f01067b3:	90                   	nop
f01067b4:	8d 74 26 00          	lea    0x0(%esi,%eiz,1),%esi
f01067b8:	31 ff                	xor    %edi,%edi
f01067ba:	b9 01 00 00 00       	mov    $0x1,%ecx
f01067bf:	e9 60 ff ff ff       	jmp    f0106724 <__udivdi3+0x74>
f01067c4:	8d 74 26 00          	lea    0x0(%esi,%eiz,1),%esi
f01067c8:	8d 4f ff             	lea    -0x1(%edi),%ecx
f01067cb:	31 ff                	xor    %edi,%edi
f01067cd:	89 c8                	mov    %ecx,%eax
f01067cf:	89 fa                	mov    %edi,%edx
f01067d1:	83 c4 10             	add    $0x10,%esp
f01067d4:	5e                   	pop    %esi
f01067d5:	5f                   	pop    %edi
f01067d6:	5d                   	pop    %ebp
f01067d7:	c3                   	ret    
	...

f01067e0 <__umoddi3>:
f01067e0:	55                   	push   %ebp
f01067e1:	89 e5                	mov    %esp,%ebp
f01067e3:	57                   	push   %edi
f01067e4:	56                   	push   %esi
f01067e5:	83 ec 20             	sub    $0x20,%esp
f01067e8:	8b 55 14             	mov    0x14(%ebp),%edx
f01067eb:	8b 4d 08             	mov    0x8(%ebp),%ecx
f01067ee:	8b 7d 10             	mov    0x10(%ebp),%edi
f01067f1:	8b 75 0c             	mov    0xc(%ebp),%esi
f01067f4:	85 d2                	test   %edx,%edx
f01067f6:	89 c8                	mov    %ecx,%eax
f01067f8:	89 4d f4             	mov    %ecx,-0xc(%ebp)
f01067fb:	75 13                	jne    f0106810 <__umoddi3+0x30>
f01067fd:	39 f7                	cmp    %esi,%edi
f01067ff:	76 3f                	jbe    f0106840 <__umoddi3+0x60>
f0106801:	89 f2                	mov    %esi,%edx
f0106803:	f7 f7                	div    %edi
f0106805:	89 d0                	mov    %edx,%eax
f0106807:	31 d2                	xor    %edx,%edx
f0106809:	83 c4 20             	add    $0x20,%esp
f010680c:	5e                   	pop    %esi
f010680d:	5f                   	pop    %edi
f010680e:	5d                   	pop    %ebp
f010680f:	c3                   	ret    
f0106810:	39 f2                	cmp    %esi,%edx
f0106812:	77 4c                	ja     f0106860 <__umoddi3+0x80>
f0106814:	0f bd ca             	bsr    %edx,%ecx
f0106817:	83 f1 1f             	xor    $0x1f,%ecx
f010681a:	89 4d f0             	mov    %ecx,-0x10(%ebp)
f010681d:	75 51                	jne    f0106870 <__umoddi3+0x90>
f010681f:	3b 7d f4             	cmp    -0xc(%ebp),%edi
f0106822:	0f 87 e0 00 00 00    	ja     f0106908 <__umoddi3+0x128>
f0106828:	8b 45 f4             	mov    -0xc(%ebp),%eax
f010682b:	29 f8                	sub    %edi,%eax
f010682d:	19 d6                	sbb    %edx,%esi
f010682f:	89 45 f4             	mov    %eax,-0xc(%ebp)
f0106832:	8b 45 f4             	mov    -0xc(%ebp),%eax
f0106835:	89 f2                	mov    %esi,%edx
f0106837:	83 c4 20             	add    $0x20,%esp
f010683a:	5e                   	pop    %esi
f010683b:	5f                   	pop    %edi
f010683c:	5d                   	pop    %ebp
f010683d:	c3                   	ret    
f010683e:	66 90                	xchg   %ax,%ax
f0106840:	85 ff                	test   %edi,%edi
f0106842:	75 0b                	jne    f010684f <__umoddi3+0x6f>
f0106844:	b8 01 00 00 00       	mov    $0x1,%eax
f0106849:	31 d2                	xor    %edx,%edx
f010684b:	f7 f7                	div    %edi
f010684d:	89 c7                	mov    %eax,%edi
f010684f:	89 f0                	mov    %esi,%eax
f0106851:	31 d2                	xor    %edx,%edx
f0106853:	f7 f7                	div    %edi
f0106855:	8b 45 f4             	mov    -0xc(%ebp),%eax
f0106858:	f7 f7                	div    %edi
f010685a:	eb a9                	jmp    f0106805 <__umoddi3+0x25>
f010685c:	8d 74 26 00          	lea    0x0(%esi,%eiz,1),%esi
f0106860:	89 c8                	mov    %ecx,%eax
f0106862:	89 f2                	mov    %esi,%edx
f0106864:	83 c4 20             	add    $0x20,%esp
f0106867:	5e                   	pop    %esi
f0106868:	5f                   	pop    %edi
f0106869:	5d                   	pop    %ebp
f010686a:	c3                   	ret    
f010686b:	90                   	nop
f010686c:	8d 74 26 00          	lea    0x0(%esi,%eiz,1),%esi
f0106870:	0f b6 4d f0          	movzbl -0x10(%ebp),%ecx
f0106874:	d3 e2                	shl    %cl,%edx
f0106876:	89 55 f4             	mov    %edx,-0xc(%ebp)
f0106879:	ba 20 00 00 00       	mov    $0x20,%edx
f010687e:	2b 55 f0             	sub    -0x10(%ebp),%edx
f0106881:	89 55 ec             	mov    %edx,-0x14(%ebp)
f0106884:	0f b6 4d ec          	movzbl -0x14(%ebp),%ecx
f0106888:	89 fa                	mov    %edi,%edx
f010688a:	d3 ea                	shr    %cl,%edx
f010688c:	0f b6 4d f0          	movzbl -0x10(%ebp),%ecx
f0106890:	0b 55 f4             	or     -0xc(%ebp),%edx
f0106893:	d3 e7                	shl    %cl,%edi
f0106895:	0f b6 4d ec          	movzbl -0x14(%ebp),%ecx
f0106899:	89 55 f4             	mov    %edx,-0xc(%ebp)
f010689c:	89 f2                	mov    %esi,%edx
f010689e:	89 7d e8             	mov    %edi,-0x18(%ebp)
f01068a1:	89 c7                	mov    %eax,%edi
f01068a3:	d3 ea                	shr    %cl,%edx
f01068a5:	0f b6 4d f0          	movzbl -0x10(%ebp),%ecx
f01068a9:	89 55 e4             	mov    %edx,-0x1c(%ebp)
f01068ac:	89 c2                	mov    %eax,%edx
f01068ae:	d3 e6                	shl    %cl,%esi
f01068b0:	0f b6 4d ec          	movzbl -0x14(%ebp),%ecx
f01068b4:	d3 ea                	shr    %cl,%edx
f01068b6:	0f b6 4d f0          	movzbl -0x10(%ebp),%ecx
f01068ba:	09 d6                	or     %edx,%esi
f01068bc:	89 f0                	mov    %esi,%eax
f01068be:	8b 75 e4             	mov    -0x1c(%ebp),%esi
f01068c1:	d3 e7                	shl    %cl,%edi
f01068c3:	89 f2                	mov    %esi,%edx
f01068c5:	f7 75 f4             	divl   -0xc(%ebp)
f01068c8:	89 d6                	mov    %edx,%esi
f01068ca:	f7 65 e8             	mull   -0x18(%ebp)
f01068cd:	39 d6                	cmp    %edx,%esi
f01068cf:	72 2b                	jb     f01068fc <__umoddi3+0x11c>
f01068d1:	39 c7                	cmp    %eax,%edi
f01068d3:	72 23                	jb     f01068f8 <__umoddi3+0x118>
f01068d5:	0f b6 4d f0          	movzbl -0x10(%ebp),%ecx
f01068d9:	29 c7                	sub    %eax,%edi
f01068db:	19 d6                	sbb    %edx,%esi
f01068dd:	89 f0                	mov    %esi,%eax
f01068df:	89 f2                	mov    %esi,%edx
f01068e1:	d3 ef                	shr    %cl,%edi
f01068e3:	0f b6 4d ec          	movzbl -0x14(%ebp),%ecx
f01068e7:	d3 e0                	shl    %cl,%eax
f01068e9:	0f b6 4d f0          	movzbl -0x10(%ebp),%ecx
f01068ed:	09 f8                	or     %edi,%eax
f01068ef:	d3 ea                	shr    %cl,%edx
f01068f1:	83 c4 20             	add    $0x20,%esp
f01068f4:	5e                   	pop    %esi
f01068f5:	5f                   	pop    %edi
f01068f6:	5d                   	pop    %ebp
f01068f7:	c3                   	ret    
f01068f8:	39 d6                	cmp    %edx,%esi
f01068fa:	75 d9                	jne    f01068d5 <__umoddi3+0xf5>
f01068fc:	2b 45 e8             	sub    -0x18(%ebp),%eax
f01068ff:	1b 55 f4             	sbb    -0xc(%ebp),%edx
f0106902:	eb d1                	jmp    f01068d5 <__umoddi3+0xf5>
f0106904:	8d 74 26 00          	lea    0x0(%esi,%eiz,1),%esi
f0106908:	39 f2                	cmp    %esi,%edx
f010690a:	0f 82 18 ff ff ff    	jb     f0106828 <__umoddi3+0x48>
f0106910:	e9 1d ff ff ff       	jmp    f0106832 <__umoddi3+0x52>
